OSDN Git Service

2009-04-02 Chao-ying Fu <fu@mips.com>
[pf3gnuchains/gcc-fork.git] / gcc / config / mips / mips.h
index 30d77eb..fbcfdca 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, 2002, 2003, 2004, 2005, 2007, 2008
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Contributed by A. Lichnewsky (lich@inria.inria.fr).
    Changed by Michael Meissner (meissner@osf.org).
@@ -50,6 +50,7 @@ enum processor_type {
   PROCESSOR_LOONGSON_2E,
   PROCESSOR_LOONGSON_2F,
   PROCESSOR_M4K,
+  PROCESSOR_OCTEON,
   PROCESSOR_R3900,
   PROCESSOR_R6000,
   PROCESSOR_R4000,
@@ -66,6 +67,7 @@ enum processor_type {
   PROCESSOR_R7000,
   PROCESSOR_R8000,
   PROCESSOR_R9000,
+  PROCESSOR_R10000,
   PROCESSOR_SB1,
   PROCESSOR_SB1A,
   PROCESSOR_SR71000,
@@ -253,6 +255,7 @@ enum mips_code_readable_setting {
 #define TARGET_MIPS5500             (mips_arch == PROCESSOR_R5500)
 #define TARGET_MIPS7000             (mips_arch == PROCESSOR_R7000)
 #define TARGET_MIPS9000             (mips_arch == PROCESSOR_R9000)
+#define TARGET_OCTEON              (mips_arch == PROCESSOR_OCTEON)
 #define TARGET_SB1                  (mips_arch == PROCESSOR_SB1                \
                                     || mips_arch == PROCESSOR_SB1A)
 #define TARGET_SR71K                (mips_arch == PROCESSOR_SR71000)
@@ -279,6 +282,7 @@ enum mips_code_readable_setting {
 #define TUNE_MIPS6000               (mips_tune == PROCESSOR_R6000)
 #define TUNE_MIPS7000               (mips_tune == PROCESSOR_R7000)
 #define TUNE_MIPS9000               (mips_tune == PROCESSOR_R9000)
+#define TUNE_OCTEON                (mips_tune == PROCESSOR_OCTEON)
 #define TUNE_SB1                    (mips_tune == PROCESSOR_SB1                \
                                     || mips_tune == PROCESSOR_SB1A)
 
@@ -525,10 +529,19 @@ enum mips_code_readable_setting {
          builtin_define ("_MIPSEL");                                   \
        }                                                               \
                                                                         \
+      /* Whether calls should go through $25.  The separate __PIC__    \
+        macro indicates whether abicalls code might use a GOT.  */     \
+      if (TARGET_ABICALLS)                                             \
+       builtin_define ("__mips_abicalls");                             \
+                                                                       \
       /* Whether Loongson vector modes are enabled.  */                 \
       if (TARGET_LOONGSON_VECTORS)                                     \
         builtin_define ("__mips_loongson_vector_rev");                  \
                                                                        \
+      /* Historical Octeon macro.  */                                  \
+      if (TARGET_OCTEON)                                               \
+       builtin_define ("__OCTEON__");                                  \
+                                                                       \
       /* Macros dependent on the C dialect.  */                                \
       if (preprocessing_asm_p ())                                      \
        {                                                               \
@@ -557,6 +570,9 @@ enum mips_code_readable_setting {
                                                                        \
       if (mips_abi == ABI_EABI)                                                \
        builtin_define ("__mips_eabi");                                 \
+                                                                       \
+      if (TARGET_CACHE_BUILTIN)                                                \
+       builtin_define ("__GCC_HAVE_BUILTIN_MIPS_CACHE");               \
     }                                                                  \
   while (0)
 
@@ -688,12 +704,13 @@ enum mips_code_readable_setting {
      %{march=mips1|march=r2000|march=r3000|march=r3900:-mips1} \
      %{march=mips2|march=r6000:-mips2} \
      %{march=mips3|march=r4*|march=vr4*|march=orion|march=loongson2*:-mips3} \
-     %{march=mips4|march=r8000|march=vr5*|march=rm7000|march=rm9000:-mips4} \
+     %{march=mips4|march=r8000|march=vr5*|march=rm7000|march=rm9000 \
+       |march=r10000|march=r12000|march=r14000|march=r16000:-mips4} \
      %{march=mips32|march=4kc|march=4km|march=4kp|march=4ksc:-mips32} \
      %{march=mips32r2|march=m4k|march=4ke*|march=4ksd|march=24k* \
        |march=34k*|march=74k*: -mips32r2} \
      %{march=mips64|march=5k*|march=20k*|march=sb1*|march=sr71000: -mips64} \
-     %{march=mips64r2: -mips64r2} \
+     %{march=mips64r2|march=octeon: -mips64r2} \
      %{!march=*: -" MULTILIB_ISA_DEFAULT "}}"
 
 /* A spec that infers a -mhard-float or -msoft-float setting from an
@@ -703,7 +720,7 @@ enum mips_code_readable_setting {
 #define MIPS_ARCH_FLOAT_SPEC \
   "%{mhard-float|msoft-float|march=mips*:; \
      march=vr41*|march=m4k|march=4k*|march=24kc|march=24kec \
-     |march=34kc|march=74kc|march=5kc: -msoft-float; \
+     |march=34kc|march=74kc|march=5kc|march=octeon: -msoft-float; \
      march=*: -mhard-float}"
 
 /* A spec condition that matches 32-bit options.  It only works if
@@ -731,6 +748,12 @@ enum mips_code_readable_setting {
   {"mips-plt", "%{!mplt:%{!mno-plt:-m%(VALUE)}}" }
 
 
+/* A spec that infers the -mdsp setting from an -march argument.  */
+#define BASE_DRIVER_SELF_SPECS \
+  "%{!mno-dsp:%{march=24ke*|march=34k*|march=74k*: -mdsp}}"
+
+#define DRIVER_SELF_SPECS BASE_DRIVER_SELF_SPECS
+
 #define GENERATE_DIVIDE_TRAPS (TARGET_DIVIDE_TRAPS \
                                && ISA_HAS_COND_TRAP)
 
@@ -744,9 +767,15 @@ enum mips_code_readable_setting {
 /* Likewise for 32-bit regs.  */
 #define ABI_NEEDS_32BIT_REGS   (mips_abi == ABI_32)
 
-/* True if symbols are 64 bits wide.  At present, n64 is the only
-   ABI for which this is true.  */
-#define ABI_HAS_64BIT_SYMBOLS  (mips_abi == ABI_64 && !TARGET_SYM32)
+/* True if the file format uses 64-bit symbols.  At present, this is
+   only true for n64, which uses 64-bit ELF.  */
+#define FILE_HAS_64BIT_SYMBOLS (mips_abi == ABI_64)
+
+/* True if symbols are 64 bits wide.  This is usually determined by
+   the ABI's file format, but it can be overridden by -msym32.  Note that
+   overriding the size with -msym32 changes the ABI of relocatable objects,
+   although it doesn't change the ABI of a fully-linked object.  */
+#define ABI_HAS_64BIT_SYMBOLS  (FILE_HAS_64BIT_SYMBOLS && !TARGET_SYM32)
 
 /* ISA has instructions for managing 64-bit fp and gp regs (e.g. mips3).  */
 #define ISA_HAS_64BIT_REGS     (ISA_MIPS3                              \
@@ -772,6 +801,11 @@ enum mips_code_readable_setting {
                                  || ISA_MIPS64R2)                      \
                                 && !TARGET_MIPS16)
 
+/* ISA has a three-operand multiplication instruction.  */
+#define ISA_HAS_DMUL3          (TARGET_64BIT                           \
+                                && TARGET_OCTEON                       \
+                                && !TARGET_MIPS16)
+
 /* ISA has the floating-point conditional move instructions introduced
    in mips4.  */
 #define ISA_HAS_FP_CONDMOVE    ((ISA_MIPS4                             \
@@ -897,6 +931,7 @@ enum mips_code_readable_setting {
 
 /* ISA has data prefetch instructions.  This controls use of 'pref'.  */
 #define ISA_HAS_PREFETCH       ((ISA_MIPS4                             \
+                                 || TARGET_LOONGSON_2EF                \
                                  || ISA_MIPS32                         \
                                  || ISA_MIPS32R2                       \
                                  || ISA_MIPS64                         \
@@ -996,6 +1031,30 @@ enum mips_code_readable_setting {
   (target_flags_explicit & MASK_LLSC   \
    ? TARGET_LLSC && !TARGET_MIPS16     \
    : ISA_HAS_LL_SC)
+
+/* ISA includes the baddu instruction.  */
+#define ISA_HAS_BADDU          (TARGET_OCTEON && !TARGET_MIPS16)
+
+/* ISA includes the bbit* instructions.  */
+#define ISA_HAS_BBIT           (TARGET_OCTEON && !TARGET_MIPS16)
+
+/* ISA includes the cins instruction.  */
+#define ISA_HAS_CINS           (TARGET_OCTEON && !TARGET_MIPS16)
+
+/* ISA includes the exts instruction.  */
+#define ISA_HAS_EXTS           (TARGET_OCTEON && !TARGET_MIPS16)
+
+/* ISA includes the seq and sne instructions.  */
+#define ISA_HAS_SEQ_SNE                (TARGET_OCTEON && !TARGET_MIPS16)
+
+/* ISA includes the pop instruction.  */
+#define ISA_HAS_POP            (TARGET_OCTEON && !TARGET_MIPS16)
+
+/* The CACHE instruction is available in non-MIPS16 code.  */
+#define TARGET_CACHE_BUILTIN (mips_isa >= 3)
+
+/* The CACHE instruction is available.  */
+#define ISA_HAS_CACHE (TARGET_CACHE_BUILTIN && !TARGET_MIPS16)
 \f
 /* Add -G xx support.  */
 
@@ -1165,7 +1224,14 @@ enum mips_code_readable_setting {
 #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
 #endif
 
-#define DWARF2_ADDR_SIZE (ABI_HAS_64BIT_SYMBOLS ? 8 : 4)
+/* The size of DWARF addresses should be the same as the size of symbols
+   in the target file format.  They shouldn't depend on things like -msym32,
+   because many DWARF consumers do not allow the mixture of address sizes
+   that one would then get from linking -msym32 code with -msym64 code.
+
+   Note that the default POINTER_SIZE test is not appropriate for MIPS.
+   EABI64 has 64-bit pointers but uses 32-bit ELF.  */
+#define DWARF2_ADDR_SIZE (FILE_HAS_64BIT_SYMBOLS ? 8 : 4)
 
 /* By default, turn on GDB extensions.  */
 #define DEFAULT_GDB_EXTENSIONS 1
@@ -1556,6 +1622,9 @@ enum mips_code_readable_setting {
 #define GP_REG_LAST  31
 #define GP_REG_NUM   (GP_REG_LAST - GP_REG_FIRST + 1)
 #define GP_DBX_FIRST 0
+#define K0_REG_NUM   (GP_REG_FIRST + 26)
+#define K1_REG_NUM   (GP_REG_FIRST + 27)
+#define KERNEL_REG_P(REGNO)    (IN_RANGE (REGNO, K0_REG_NUM, K1_REG_NUM))
 
 #define FP_REG_FIRST 32
 #define FP_REG_LAST  63
@@ -1583,6 +1652,10 @@ enum mips_code_readable_setting {
 #define COP0_REG_LAST 111
 #define COP0_REG_NUM (COP0_REG_LAST - COP0_REG_FIRST + 1)
 
+#define COP0_STATUS_REG_NUM    (COP0_REG_FIRST + 12)
+#define COP0_CAUSE_REG_NUM     (COP0_REG_FIRST + 13)
+#define COP0_EPC_REG_NUM       (COP0_REG_FIRST + 14)
+
 #define COP2_REG_FIRST 112
 #define COP2_REG_LAST 143
 #define COP2_REG_NUM (COP2_REG_LAST - COP2_REG_FIRST + 1)
@@ -1601,6 +1674,17 @@ enum mips_code_readable_setting {
 #define HI_REGNUM      (TARGET_BIG_ENDIAN ? MD_REG_FIRST : MD_REG_FIRST + 1)
 #define LO_REGNUM      (TARGET_BIG_ENDIAN ? MD_REG_FIRST + 1 : MD_REG_FIRST)
 
+/* A few bitfield locations for the coprocessor registers.  */
+/* Request Interrupt Priority Level is from bit 10 to bit 15 of
+   the cause register for the EIC interrupt mode.  */
+#define CAUSE_IPL      10
+/* Interrupt Priority Level is from bit 10 to bit 15 of the status register.  */
+#define SR_IPL         10
+/* Exception Level is at bit 1 of the status register.  */
+#define SR_EXL         1
+/* Interrupt Enable is at bit 0 of the status register.  */
+#define SR_IE          0
+
 /* FPSW_REGNUM is the single condition code used if !ISA_HAS_8CC.
    If ISA_HAS_8CC, it should not be used, and an arbitrary ST_REG
    should be used instead.  */
@@ -1688,11 +1772,18 @@ enum mips_code_readable_setting {
    incoming arguments, the static chain pointer, or the frame pointer.
    The epilogue temporary mustn't conflict with the return registers,
    the PIC call register ($25), the frame pointer, the EH stack adjustment,
-   or the EH data registers.  */
+   or the EH data registers.
+
+   If we're generating interrupt handlers, we use K0 as a temporary register
+   in prologue/epilogue code.  */
 
 #define MIPS16_PIC_TEMP_REGNUM (GP_REG_FIRST + 2)
-#define MIPS_PROLOGUE_TEMP_REGNUM (GP_REG_FIRST + 3)
-#define MIPS_EPILOGUE_TEMP_REGNUM (GP_REG_FIRST + (TARGET_MIPS16 ? 6 : 8))
+#define MIPS_PROLOGUE_TEMP_REGNUM \
+  (cfun->machine->interrupt_handler_p ? K0_REG_NUM : GP_REG_FIRST + 3)
+#define MIPS_EPILOGUE_TEMP_REGNUM              \
+  (cfun->machine->interrupt_handler_p          \
+   ? K0_REG_NUM                                        \
+   : GP_REG_FIRST + (TARGET_MIPS16 ? 6 : 8))
 
 #define MIPS16_PIC_TEMP gen_rtx_REG (Pmode, MIPS16_PIC_TEMP_REGNUM)
 #define MIPS_PROLOGUE_TEMP(MODE) gen_rtx_REG (MODE, MIPS_PROLOGUE_TEMP_REGNUM)
@@ -1756,17 +1847,14 @@ enum reg_class
   COP0_REGS,                   /* generic coprocessor classes */
   COP2_REGS,
   COP3_REGS,
-  HI_AND_GR_REGS,              /* union classes */
-  LO_AND_GR_REGS,
-  HI_AND_FP_REGS,
-  COP0_AND_GR_REGS,
-  COP2_AND_GR_REGS,
-  COP3_AND_GR_REGS,
-  ALL_COP_REGS,
-  ALL_COP_AND_GR_REGS,
   ST_REGS,                     /* status registers (fp status) */
   DSP_ACC_REGS,                        /* DSP accumulator registers */
   ACC_REGS,                    /* Hi/Lo and DSP accumulator registers */
+  FRAME_REGS,                  /* $arg and $frame */
+  GR_AND_MD0_REGS,             /* union classes */
+  GR_AND_MD1_REGS,
+  GR_AND_MD_REGS,
+  GR_AND_ACC_REGS,
   ALL_REGS,                    /* all registers */
   LIM_REG_CLASSES              /* max value + 1 */
 };
@@ -1797,17 +1885,14 @@ enum reg_class
   "COP0_REGS",                                                         \
   "COP2_REGS",                                                         \
   "COP3_REGS",                                                         \
-  "HI_AND_GR_REGS",                                                    \
-  "LO_AND_GR_REGS",                                                    \
-  "HI_AND_FP_REGS",                                                    \
-  "COP0_AND_GR_REGS",                                                  \
-  "COP2_AND_GR_REGS",                                                  \
-  "COP3_AND_GR_REGS",                                                  \
-  "ALL_COP_REGS",                                                      \
-  "ALL_COP_AND_GR_REGS",                                               \
   "ST_REGS",                                                           \
   "DSP_ACC_REGS",                                                      \
   "ACC_REGS",                                                          \
+  "FRAME_REGS",                                                                \
+  "GR_AND_MD0_REGS",                                                   \
+  "GR_AND_MD1_REGS",                                                   \
+  "GR_AND_MD_REGS",                                                    \
+  "GR_AND_ACC_REGS",                                                   \
   "ALL_REGS"                                                           \
 }
 
@@ -1824,33 +1909,30 @@ enum reg_class
 
 #define REG_CLASS_CONTENTS                                                                             \
 {                                                                                                      \
-  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* no registers */      \
-  { 0x000300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* mips16 registers */  \
-  { 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* mips16 T register */ \
-  { 0x010300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* mips16 and T regs */ \
-  { 0x02000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* SVR4 PIC function address register */ \
-  { 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* only $v1 */ \
-  { 0xfdffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* Every other GPR except $25 */   \
-  { 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* integer registers */ \
-  { 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* floating registers*/ \
-  { 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000 },  /* hi register */       \
-  { 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000 },  /* lo register */       \
-  { 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000 },  /* mul/div registers */ \
-  { 0x00000000, 0x00000000, 0xffff0000, 0x0000ffff, 0x00000000, 0x00000000 },   /* cop0 registers */    \
-  { 0x00000000, 0x00000000, 0x00000000, 0xffff0000, 0x0000ffff, 0x00000000 },   /* cop2 registers */    \
-  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffff0000, 0x0000ffff },   /* cop3 registers */    \
-  { 0xffffffff, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000 },  /* union classes */     \
-  { 0xffffffff, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000 },                          \
-  { 0x00000000, 0xffffffff, 0x00000001, 0x00000000, 0x00000000, 0x00000000 },                          \
-  { 0xffffffff, 0x00000000, 0xffff0000, 0x0000ffff, 0x00000000, 0x00000000 },                          \
-  { 0xffffffff, 0x00000000, 0x00000000, 0xffff0000, 0x0000ffff, 0x00000000 },                          \
-  { 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0xffff0000, 0x0000ffff },                           \
-  { 0x00000000, 0x00000000, 0xffff0000, 0xffffffff, 0xffffffff, 0x0000ffff },                           \
-  { 0xffffffff, 0x00000000, 0xffff0000, 0xffffffff, 0xffffffff, 0x0000ffff },                           \
-  { 0x00000000, 0x00000000, 0x000007f8, 0x00000000, 0x00000000, 0x00000000 },  /* status registers */  \
-  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x003f0000 },  /* dsp accumulator registers */ \
-  { 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x003f0000 },  /* hi/lo and dsp accumulator registers */       \
-  { 0xffffffff, 0xffffffff, 0xffff07ff, 0xffffffff, 0xffffffff, 0x0fffffff }   /* all registers */     \
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* NO_REGS */           \
+  { 0x000300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* M16_REGS */          \
+  { 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* T_REG */             \
+  { 0x010300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* M16_T_REGS */        \
+  { 0x02000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* PIC_FN_ADDR_REG */   \
+  { 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* V1_REG */            \
+  { 0xfdffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* LEA_REGS */          \
+  { 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* GR_REGS */           \
+  { 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* FP_REGS */           \
+  { 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000 },  /* MD0_REG */           \
+  { 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000 },  /* MD1_REG */           \
+  { 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000 },  /* MD_REGS */           \
+  { 0x00000000, 0x00000000, 0xffff0000, 0x0000ffff, 0x00000000, 0x00000000 },   /* COP0_REGS */                \
+  { 0x00000000, 0x00000000, 0x00000000, 0xffff0000, 0x0000ffff, 0x00000000 },   /* COP2_REGS */                \
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffff0000, 0x0000ffff },   /* COP3_REGS */                \
+  { 0x00000000, 0x00000000, 0x000007f8, 0x00000000, 0x00000000, 0x00000000 },  /* ST_REGS */           \
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x003f0000 },  /* DSP_ACC_REGS */      \
+  { 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x003f0000 },  /* ACC_REGS */          \
+  { 0x00000000, 0x00000000, 0x00006000, 0x00000000, 0x00000000, 0x00000000 },  /* FRAME_REGS */        \
+  { 0xffffffff, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000 },  /* GR_AND_MD0_REGS */   \
+  { 0xffffffff, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000 },  /* GR_AND_MD1_REGS */   \
+  { 0xffffffff, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000 },  /* GR_AND_MD_REGS */    \
+  { 0xffffffff, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x003f0000 },  /* GR_AND_ACC_REGS */   \
+  { 0xffffffff, 0xffffffff, 0xffff67ff, 0xffffffff, 0xffffffff, 0x0fffffff }   /* ALL_REGS */          \
 }
 
 
@@ -1882,24 +1964,50 @@ enum reg_class
 
 #define SMALL_REGISTER_CLASSES (TARGET_MIPS16)
 
-/* REG_ALLOC_ORDER is to order in which to allocate registers.  This
-   is the default value (allocate the registers in numeric order).  We
-   define it just so that we can override it for the mips16 target in
-   ORDER_REGS_FOR_LOCAL_ALLOC.  */
+/* We generally want to put call-clobbered registers ahead of
+   call-saved ones.  (IRA expects this.)  */
 
 #define REG_ALLOC_ORDER                                                        \
-{  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,      \
-  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,      \
+{ /* Accumulator registers.  When GPRs and accumulators have equal     \
+     cost, we generally prefer to use accumulators.  For example,      \
+     a division of multiplication result is better allocated to LO,    \
+     so that we put the MFLO at the point of use instead of at the     \
+     point of definition.  It's also needed if we're to take advantage \
+     of the extra accumulators available with -mdspr2.  In some cases, \
+     it can also help to reduce register pressure.  */                 \
+  64, 65,176,177,178,179,180,181,                                      \
+  /* Call-clobbered GPRs.  */                                          \
+  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,           \
+  24, 25, 31,                                                          \
+  /* The global pointer.  This is call-clobbered for o32 and o64       \
+     abicalls, call-saved for n32 and n64 abicalls, and a program      \
+     invariant otherwise.  Putting it between the call-clobbered       \
+     and call-saved registers should cope with all eventualities.  */  \
+  28,                                                                  \
+  /* Call-saved GPRs.  */                                              \
+  16, 17, 18, 19, 20, 21, 22, 23, 30,                                  \
+  /* GPRs that can never be exposed to the register allocator.  */     \
+  0,  26, 27, 29,                                                      \
+  /* Call-clobbered FPRs.  */                                          \
   32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,      \
-  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,      \
-  64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,      \
+  48, 49, 50, 51,                                                      \
+  /* FPRs that are usually call-saved.  The odd ones are actually      \
+     call-clobbered for n32, but listing them ahead of the even                \
+     registers might encourage the register allocator to fragment      \
+     the available FPR pairs.  We need paired FPRs to store long       \
+     doubles, so it isn't clear that using a different order           \
+     for n32 would be a win.  */                                       \
+  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,                      \
+  /* None of the remaining classes have defined call-saved             \
+     registers.  */                                                    \
+  66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,              \
   80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,      \
   96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,     \
   112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,     \
   128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,     \
   144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,     \
   160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,     \
-  176,177,178,179,180,181,182,183,184,185,186,187                      \
+  182,183,184,185,186,187                                              \
 }
 
 /* ORDER_REGS_FOR_LOCAL_ALLOC is a macro which permits reg_alloc_order
@@ -2201,14 +2309,7 @@ typedef struct mips_args {
        (mips_abi == ABI_EABI && UNITS_PER_FPVALUE >= UNITS_PER_DOUBLE)
 
 \f
-/* Say that the epilogue uses the return address register.  Note that
-   in the case of sibcalls, the values "used by the epilogue" are
-   considered live at the start of the called function.
-
-   If using a GOT, say that the epilogue also uses GOT_VERSION_REGNUM.
-   See the comment above load_call<mode> for details.  */
-#define EPILOGUE_USES(REGNO) \
-  ((REGNO) == 31 || (TARGET_USE_GOT && (REGNO) == GOT_VERSION_REGNUM))
+#define EPILOGUE_USES(REGNO)   mips_epilogue_uses (REGNO)
 
 /* Treat LOC as a byte offset from the stack pointer and round it up
    to the next fully-aligned offset.  */
@@ -2223,6 +2324,14 @@ typedef struct mips_args {
 {                                                                      \
   if (TARGET_MIPS16)                                                   \
     sorry ("mips16 function profiling");                               \
+  if (TARGET_LONG_CALLS)                                               \
+    {                                                                  \
+      /*  For TARGET_LONG_CALLS use $3 for the address of _mcount.  */ \
+      if (Pmode == DImode)                                             \
+       fprintf (FILE, "\tdla\t%s,_mcount\n", reg_names[GP_REG_FIRST + 3]); \
+      else                                                             \
+       fprintf (FILE, "\tla\t%s,_mcount\n", reg_names[GP_REG_FIRST + 3]); \
+    }                                                                  \
   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]);  \
@@ -2239,7 +2348,10 @@ typedef struct mips_args {
               reg_names[STACK_POINTER_REGNUM],                         \
               Pmode == DImode ? 16 : 8);                               \
     }                                                                  \
-  fprintf (FILE, "\tjal\t_mcount\n");                                   \
+  if (TARGET_LONG_CALLS)                                               \
+    fprintf (FILE, "\tjalr\t%s\n", reg_names[GP_REG_FIRST + 3]);       \
+  else                                                                 \
+    fprintf (FILE, "\tjal\t_mcount\n");                                        \
   fprintf (FILE, "\t.set\tat\n");                                      \
   /* _mcount treats $2 as the static chain register.  */               \
   if (cfun->static_chain_decl != NULL)                                 \
@@ -2542,7 +2654,7 @@ typedef struct mips_args {
 /* A C expression for the cost of a branch instruction.  A value of
    1 is the default; other values are interpreted relative to that.  */
 
-#define BRANCH_COST mips_branch_cost
+#define BRANCH_COST(speed_p, predictable_p) mips_branch_cost
 #define LOGICAL_OP_NON_SHORT_CIRCUIT 0
 
 /* If defined, modifies the length assigned to instruction INSN as a
@@ -2769,6 +2881,32 @@ while (0)
 #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)                  \
   sprintf ((LABEL), "*%s%s%ld", (LOCAL_LABEL_PREFIX), (PREFIX), (long)(NUM))
 
+/* Print debug labels as "foo = ." rather than "foo:" because they should
+   represent a byte pointer rather than an ISA-encoded address.  This is
+   particularly important for code like:
+
+       $LFBxxx = .
+               .cfi_startproc
+               ...
+               .section .gcc_except_table,...
+               ...
+               .uleb128 foo-$LFBxxx
+
+   The .uleb128 requies $LFBxxx to match the FDE start address, which is
+   likewise a byte pointer rather than an ISA-encoded address.
+
+   At the time of writing, this hook is not used for the function end
+   label:
+
+       $LFExxx:
+               .end foo
+
+   But this doesn't matter, because GAS doesn't treat a pre-.end label
+   as a MIPS16 one anyway.  */
+
+#define ASM_OUTPUT_DEBUG_LABEL(FILE, PREFIX, NUM)                      \
+  fprintf (FILE, "%s%s%d = .\n", LOCAL_LABEL_PREFIX, PREFIX, NUM)
+
 /* This is how to output an element of a case-vector that is absolute.  */
 
 #define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE)                         \
@@ -2925,7 +3063,7 @@ while (0)
    we'll have to generate a load/store pair for each, halve the
    value of MIPS_CALL_RATIO to take that into account.  */
 
-#define MOVE_RATIO                                     \
+#define MOVE_RATIO(speed)                              \
   (HAVE_movmemsi                                       \
    ? MIPS_MAX_MOVE_BYTES_STRAIGHT / MOVE_MAX           \
    : MIPS_CALL_RATIO / 2)
@@ -2946,20 +3084,20 @@ while (0)
          ? (SIZE) < UNITS_PER_WORD                             \
          : (SIZE) <= MIPS_MAX_MOVE_BYTES_STRAIGHT))            \
    : (move_by_pieces_ninsns (SIZE, ALIGN, MOVE_MAX_PIECES + 1) \
-      < (unsigned int) MOVE_RATIO))
+      < (unsigned int) MOVE_RATIO (false)))
 
 /* For CLEAR_RATIO, when optimizing for size, give a better estimate
    of the length of a memset call, but use the default otherwise.  */
 
-#define CLEAR_RATIO \
-  (optimize_size ? MIPS_CALL_RATIO : 15)
+#define CLEAR_RATIO(speed)\
+  ((speed) ? 15 : MIPS_CALL_RATIO)
 
 /* This is similar to CLEAR_RATIO, but for a non-zero constant, so when
    optimizing for size adjust the ratio to account for the overhead of
    loading the constant and replicating it across the word.  */
 
-#define SET_RATIO \
-  (optimize_size ? MIPS_CALL_RATIO - 2 : 15)
+#define SET_RATIO(speed) \
+  ((speed) ? 15 : MIPS_CALL_RATIO - 2)
 
 /* STORE_BY_PIECES_P can be used when copying a constant string, but
    in that case each word takes 3 insns (lui, ori, sw), or more in
@@ -3023,7 +3161,7 @@ while (0)
   "\tbne\t%0,%z2,2f\n"                         \
   "\t" OP "\t%@,%3\n"                          \
   "\tsc" SUFFIX "\t%@,%1\n"                    \
-  "\tbeq\t%@,%.,1b\n"                          \
+  "\tbeq%?\t%@,%.,1b\n"                                \
   "\tnop\n"                                    \
   "\tsync%-%]%>%)\n"                           \
   "2:\n"
@@ -3048,7 +3186,7 @@ while (0)
   "\tand\t%@,%0,%3\n"                          \
   OPS                                          \
   "\tsc\t%@,%1\n"                              \
-  "\tbeq\t%@,%.,1b\n"                          \
+  "\tbeq%?\t%@,%.,1b\n"                                \
   "\tnop\n"                                    \
   "\tsync%-%]%>%)\n"                           \
   "2:\n"
@@ -3068,7 +3206,7 @@ while (0)
   "1:\tll" SUFFIX "\t%@,%0\n"                  \
   "\t" INSN "\t%@,%@,%1\n"                     \
   "\tsc" SUFFIX "\t%@,%0\n"                    \
-  "\tbeq\t%@,%.,1b\n"                          \
+  "\tbeq%?\t%@,%.,1b\n"                                \
   "\tnop\n"                                    \
   "\tsync%-%]%>%)"
 
@@ -3081,24 +3219,25 @@ while (0)
 
      - Uses scratch register %4.
 
-    NOT_OP are the optional instructions to do a bit-wise not
-    operation in conjunction with an AND INSN to generate a sync_nand
-    operation.  */
-#define MIPS_SYNC_OP_12(INSN, NOT_OP)          \
+    AND_OP is an instruction done after INSN to mask INSN's result
+    with the mask.  For most operations, this is an AND with the
+    inclusive mask (%1).  For nand operations -- where the result of
+    INSN is already correctly masked -- it instead performs a bitwise
+    not.  */
+#define MIPS_SYNC_OP_12(INSN, AND_OP)          \
   "%(%<%[%|sync\n"                             \
   "1:\tll\t%4,%0\n"                            \
   "\tand\t%@,%4,%2\n"                          \
-  NOT_OP                                       \
   "\t" INSN "\t%4,%4,%z3\n"                    \
-  "\tand\t%4,%4,%1\n"                          \
+  AND_OP                                       \
   "\tor\t%@,%@,%4\n"                           \
   "\tsc\t%@,%0\n"                              \
-  "\tbeq\t%@,%.,1b\n"                          \
+  "\tbeq%?\t%@,%.,1b\n"                                \
   "\tnop\n"                                    \
   "\tsync%-%]%>%)"
 
-#define MIPS_SYNC_OP_12_NOT_NOP ""
-#define MIPS_SYNC_OP_12_NOT_NOT "\tnor\t%4,%4,%.\n"
+#define MIPS_SYNC_OP_12_AND "\tand\t%4,%4,%1\n"
+#define MIPS_SYNC_OP_12_XOR "\txor\t%4,%4,%1\n"
 
 /* Return an asm string that atomically:
 
@@ -3111,29 +3250,25 @@ while (0)
 
      - Uses scratch register %5.
 
-    NOT_OP are the optional instructions to do a bit-wise not
-    operation in conjunction with an AND INSN to generate a sync_nand
-    operation.
-
-    REG is used in conjunction with NOT_OP and is used to select the
-    register operated on by the INSN.  */
-#define MIPS_SYNC_OLD_OP_12(INSN, NOT_OP, REG) \
+    AND_OP is an instruction done after INSN to mask INSN's result
+    with the mask.  For most operations, this is an AND with the
+    inclusive mask (%1).  For nand operations -- where the result of
+    INSN is already correctly masked -- it instead performs a bitwise
+    not.  */
+#define MIPS_SYNC_OLD_OP_12(INSN, AND_OP)      \
   "%(%<%[%|sync\n"                             \
   "1:\tll\t%0,%1\n"                            \
   "\tand\t%@,%0,%3\n"                          \
-  NOT_OP                                       \
-  "\t" INSN "\t%5," REG ",%z4\n"               \
-  "\tand\t%5,%5,%2\n"                          \
+  "\t" INSN "\t%5,%0,%z4\n"                    \
+  AND_OP                                       \
   "\tor\t%@,%@,%5\n"                           \
   "\tsc\t%@,%1\n"                              \
-  "\tbeq\t%@,%.,1b\n"                          \
+  "\tbeq%?\t%@,%.,1b\n"                                \
   "\tnop\n"                                    \
   "\tsync%-%]%>%)"
 
-#define MIPS_SYNC_OLD_OP_12_NOT_NOP ""
-#define MIPS_SYNC_OLD_OP_12_NOT_NOP_REG "%0"
-#define MIPS_SYNC_OLD_OP_12_NOT_NOT "\tnor\t%5,%0,%.\n"
-#define MIPS_SYNC_OLD_OP_12_NOT_NOT_REG "%5"
+#define MIPS_SYNC_OLD_OP_12_AND "\tand\t%5,%5,%2\n"
+#define MIPS_SYNC_OLD_OP_12_XOR "\txor\t%5,%5,%2\n"
 
 /* Return an asm string that atomically:
 
@@ -3144,24 +3279,25 @@ while (0)
 
      - Sets %0 to the new value of %1.
 
-    NOT_OP are the optional instructions to do a bit-wise not
-    operation in conjunction with an AND INSN to generate a sync_nand
-    operation.  */
-#define MIPS_SYNC_NEW_OP_12(INSN, NOT_OP)      \
+    AND_OP is an instruction done after INSN to mask INSN's result
+    with the mask.  For most operations, this is an AND with the
+    inclusive mask (%1).  For nand operations -- where the result of
+    INSN is already correctly masked -- it instead performs a bitwise
+    not.  */
+#define MIPS_SYNC_NEW_OP_12(INSN, AND_OP)      \
   "%(%<%[%|sync\n"                             \
   "1:\tll\t%0,%1\n"                            \
   "\tand\t%@,%0,%3\n"                          \
-  NOT_OP                                       \
   "\t" INSN "\t%0,%0,%z4\n"                    \
-  "\tand\t%0,%0,%2\n"                          \
+  AND_OP                                       \
   "\tor\t%@,%@,%0\n"                           \
   "\tsc\t%@,%1\n"                              \
-  "\tbeq\t%@,%.,1b\n"                          \
+  "\tbeq%?\t%@,%.,1b\n"                                \
   "\tnop\n"                                    \
   "\tsync%-%]%>%)"
 
-#define MIPS_SYNC_NEW_OP_12_NOT_NOP ""
-#define MIPS_SYNC_NEW_OP_12_NOT_NOT "\tnor\t%0,%0,%.\n"
+#define MIPS_SYNC_NEW_OP_12_AND "\tand\t%0,%0,%2\n"
+#define MIPS_SYNC_NEW_OP_12_XOR "\txor\t%0,%0,%2\n"
 
 /* Return an asm string that atomically:
 
@@ -3176,7 +3312,7 @@ while (0)
   "1:\tll" SUFFIX "\t%0,%1\n"                  \
   "\t" INSN "\t%@,%0,%2\n"                     \
   "\tsc" SUFFIX "\t%@,%1\n"                    \
-  "\tbeq\t%@,%.,1b\n"                          \
+  "\tbeq%?\t%@,%.,1b\n"                                \
   "\tnop\n"                                    \
   "\tsync%-%]%>%)"
 
@@ -3193,13 +3329,13 @@ while (0)
   "1:\tll" SUFFIX "\t%0,%1\n"                  \
   "\t" INSN "\t%@,%0,%2\n"                     \
   "\tsc" SUFFIX "\t%@,%1\n"                    \
-  "\tbeq\t%@,%.,1b\n"                          \
+  "\tbeq%?\t%@,%.,1b%~\n"                      \
   "\t" INSN "\t%0,%0,%2\n"                     \
   "\tsync%-%]%>%)"
 
 /* Return an asm string that atomically:
 
-     - Sets memory reference %0 to ~%0 AND %1.
+     - Sets memory reference %0 to ~(%0 AND %1).
 
    SUFFIX is the suffix that should be added to "ll" and "sc"
    instructions.  INSN is the and instruction needed to and a register
@@ -3207,16 +3343,16 @@ while (0)
 #define MIPS_SYNC_NAND(SUFFIX, INSN)           \
   "%(%<%[%|sync\n"                             \
   "1:\tll" SUFFIX "\t%@,%0\n"                  \
-  "\tnor\t%@,%@,%.\n"                          \
   "\t" INSN "\t%@,%@,%1\n"                     \
+  "\tnor\t%@,%@,%.\n"                          \
   "\tsc" SUFFIX "\t%@,%0\n"                    \
-  "\tbeq\t%@,%.,1b\n"                          \
+  "\tbeq%?\t%@,%.,1b\n"                                \
   "\tnop\n"                                    \
   "\tsync%-%]%>%)"
 
 /* Return an asm string that atomically:
 
-     - Sets memory reference %1 to ~%1 AND %2.
+     - Sets memory reference %1 to ~(%1 AND %2).
 
      - Sets register %0 to the old value of memory reference %1.
 
@@ -3226,16 +3362,16 @@ while (0)
 #define MIPS_SYNC_OLD_NAND(SUFFIX, INSN)       \
   "%(%<%[%|sync\n"                             \
   "1:\tll" SUFFIX "\t%0,%1\n"                  \
-  "\tnor\t%@,%0,%.\n"                          \
-  "\t" INSN "\t%@,%@,%2\n"                     \
+  "\t" INSN "\t%@,%0,%2\n"                     \
+  "\tnor\t%@,%@,%.\n"                          \
   "\tsc" SUFFIX "\t%@,%1\n"                    \
-  "\tbeq\t%@,%.,1b\n"                          \
+  "\tbeq%?\t%@,%.,1b\n"                                \
   "\tnop\n"                                    \
   "\tsync%-%]%>%)"
 
 /* Return an asm string that atomically:
 
-     - Sets memory reference %1 to ~%1 AND %2.
+     - Sets memory reference %1 to ~(%1 AND %2).
 
      - Sets register %0 to the new value of memory reference %1.
 
@@ -3245,11 +3381,11 @@ while (0)
 #define MIPS_SYNC_NEW_NAND(SUFFIX, INSN)       \
   "%(%<%[%|sync\n"                             \
   "1:\tll" SUFFIX "\t%0,%1\n"                  \
-  "\tnor\t%0,%0,%.\n"                          \
-  "\t" INSN "\t%@,%0,%2\n"                     \
-  "\tsc" SUFFIX "\t%@,%1\n"                    \
-  "\tbeq\t%@,%.,1b\n"                          \
   "\t" INSN "\t%0,%0,%2\n"                     \
+  "\tnor\t%@,%0,%.\n"                          \
+  "\tsc" SUFFIX "\t%@,%1\n"                    \
+  "\tbeq%?\t%@,%.,1b%~\n"                      \
+  "\tnor\t%0,%0,%.\n"                          \
   "\tsync%-%]%>%)"
 
 /* Return an asm string that atomically:
@@ -3266,7 +3402,7 @@ while (0)
   "1:\tll" SUFFIX "\t%0,%1\n"                  \
   "\t" OP "\t%@,%2\n"                          \
   "\tsc" SUFFIX "\t%@,%1\n"                    \
-  "\tbeq\t%@,%.,1b\n"                          \
+  "\tbeq%?\t%@,%.,1b\n"                                \
   "\tnop\n"                                    \
   "\tsync%-%]%>%)"
 
@@ -3290,7 +3426,7 @@ while (0)
   "\tand\t%@,%0,%3\n"                          \
   OPS                                          \
   "\tsc\t%@,%1\n"                              \
-  "\tbeq\t%@,%.,1b\n"                          \
+  "\tbeq%?\t%@,%.,1b\n"                                \
   "\tnop\n"                                    \
   "\tsync%-%]%>%)"