OSDN Git Service

2005-12-02 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / config / mips / mips.c
index b2410a0..733b9c6 100644 (file)
@@ -1,6 +1,6 @@
 /* Subroutines used for MIPS code generation.
    Copyright (C) 1989, 1990, 1991, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by A. Lichnewsky, lich@inria.inria.fr.
    Changes by Michael Meissner, meissner@osf.org.
    64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
@@ -20,8 +20,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -132,6 +132,129 @@ enum mips_address_type {
   ADDRESS_SYMBOLIC
 };
 
+/* Classifies the prototype of a builtin function.  */
+enum mips_function_type
+{
+  MIPS_V2SF_FTYPE_V2SF,
+  MIPS_V2SF_FTYPE_V2SF_V2SF,
+  MIPS_V2SF_FTYPE_V2SF_V2SF_INT,
+  MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
+  MIPS_V2SF_FTYPE_SF_SF,
+  MIPS_INT_FTYPE_V2SF_V2SF,
+  MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
+  MIPS_INT_FTYPE_SF_SF,
+  MIPS_INT_FTYPE_DF_DF,
+  MIPS_SF_FTYPE_V2SF,
+  MIPS_SF_FTYPE_SF,
+  MIPS_SF_FTYPE_SF_SF,
+  MIPS_DF_FTYPE_DF,
+  MIPS_DF_FTYPE_DF_DF,
+
+  /* For MIPS DSP ASE  */
+  MIPS_DI_FTYPE_DI_SI,
+  MIPS_DI_FTYPE_DI_SI_SI,
+  MIPS_DI_FTYPE_DI_V2HI_V2HI,
+  MIPS_DI_FTYPE_DI_V4QI_V4QI,
+  MIPS_SI_FTYPE_DI_SI,
+  MIPS_SI_FTYPE_PTR_SI,
+  MIPS_SI_FTYPE_SI,
+  MIPS_SI_FTYPE_SI_SI,
+  MIPS_SI_FTYPE_V2HI,
+  MIPS_SI_FTYPE_V2HI_V2HI,
+  MIPS_SI_FTYPE_V4QI,
+  MIPS_SI_FTYPE_V4QI_V4QI,
+  MIPS_SI_FTYPE_VOID,
+  MIPS_V2HI_FTYPE_SI,
+  MIPS_V2HI_FTYPE_SI_SI,
+  MIPS_V2HI_FTYPE_V2HI,
+  MIPS_V2HI_FTYPE_V2HI_SI,
+  MIPS_V2HI_FTYPE_V2HI_V2HI,
+  MIPS_V2HI_FTYPE_V4QI,
+  MIPS_V2HI_FTYPE_V4QI_V2HI,
+  MIPS_V4QI_FTYPE_SI,
+  MIPS_V4QI_FTYPE_V2HI_V2HI,
+  MIPS_V4QI_FTYPE_V4QI_SI,
+  MIPS_V4QI_FTYPE_V4QI_V4QI,
+  MIPS_VOID_FTYPE_SI_SI,
+  MIPS_VOID_FTYPE_V2HI_V2HI,
+  MIPS_VOID_FTYPE_V4QI_V4QI,
+
+  /* The last type.  */
+  MIPS_MAX_FTYPE_MAX
+};
+
+/* Specifies how a builtin function should be converted into rtl.  */
+enum mips_builtin_type
+{
+  /* The builtin corresponds directly to an .md pattern.  The return
+     value is mapped to operand 0 and the arguments are mapped to
+     operands 1 and above.  */
+  MIPS_BUILTIN_DIRECT,
+
+  /* The builtin corresponds directly to an .md pattern.  There is no return
+     value and the arguments are mapped to operands 0 and above.  */
+  MIPS_BUILTIN_DIRECT_NO_TARGET,
+
+  /* The builtin corresponds to a comparison instruction followed by
+     a mips_cond_move_tf_ps pattern.  The first two arguments are the
+     values to compare and the second two arguments are the vector
+     operands for the movt.ps or movf.ps instruction (in assembly order).  */
+  MIPS_BUILTIN_MOVF,
+  MIPS_BUILTIN_MOVT,
+
+  /* The builtin corresponds to a V2SF comparison instruction.  Operand 0
+     of this instruction is the result of the comparison, which has mode
+     CCV2 or CCV4.  The function arguments are mapped to operands 1 and
+     above.  The function's return value is an SImode boolean that is
+     true under the following conditions:
+
+     MIPS_BUILTIN_CMP_ANY: one of the registers is true
+     MIPS_BUILTIN_CMP_ALL: all of the registers are true
+     MIPS_BUILTIN_CMP_LOWER: the first register is true
+     MIPS_BUILTIN_CMP_UPPER: the second register is true.  */
+  MIPS_BUILTIN_CMP_ANY,
+  MIPS_BUILTIN_CMP_ALL,
+  MIPS_BUILTIN_CMP_UPPER,
+  MIPS_BUILTIN_CMP_LOWER,
+
+  /* As above, but the instruction only sets a single $fcc register.  */
+  MIPS_BUILTIN_CMP_SINGLE,
+
+  /* For generating bposge32 branch instructions in MIPS32 DSP ASE.  */
+  MIPS_BUILTIN_BPOSGE32
+};
+
+/* Invokes MACRO (COND) for each c.cond.fmt condition.  */
+#define MIPS_FP_CONDITIONS(MACRO) \
+  MACRO (f),   \
+  MACRO (un),  \
+  MACRO (eq),  \
+  MACRO (ueq), \
+  MACRO (olt), \
+  MACRO (ult), \
+  MACRO (ole), \
+  MACRO (ule), \
+  MACRO (sf),  \
+  MACRO (ngle),        \
+  MACRO (seq), \
+  MACRO (ngl), \
+  MACRO (lt),  \
+  MACRO (nge), \
+  MACRO (le),  \
+  MACRO (ngt)
+
+/* Enumerates the codes above as MIPS_FP_COND_<X>.  */
+#define DECLARE_MIPS_COND(X) MIPS_FP_COND_ ## X
+enum mips_fp_condition {
+  MIPS_FP_CONDITIONS (DECLARE_MIPS_COND)
+};
+
+/* Index X provides the string representation of MIPS_FP_COND_<X>.  */
+#define STRINGIFY(X) #X
+static const char *const mips_fp_conditions[] = {
+  MIPS_FP_CONDITIONS (STRINGIFY)
+};
+
 /* A function to save or store a register.  The first argument is the
    register and the second is the stack slot.  */
 typedef void (*mips_save_restore_fn) (rtx, rtx);
@@ -149,6 +272,7 @@ static bool mips_valid_base_register_p (rtx, enum machine_mode, int);
 static bool mips_symbolic_address_p (enum mips_symbol_type, enum machine_mode);
 static bool mips_classify_address (struct mips_address_info *, rtx,
                                   enum machine_mode, int);
+static bool mips_cannot_force_const_mem (rtx);
 static int mips_symbol_insns (enum mips_symbol_type);
 static bool mips16_unextended_reference_p (enum machine_mode mode, rtx, rtx);
 static rtx mips_force_temporary (rtx, rtx);
@@ -176,6 +300,7 @@ static void mips_arg_info (const CUMULATIVE_ARGS *, enum machine_mode,
 static bool mips_get_unaligned_mem (rtx *, unsigned int, int, rtx *, rtx *);
 static void mips_set_architecture (const struct mips_cpu_info *);
 static void mips_set_tune (const struct mips_cpu_info *);
+static bool mips_handle_option (size_t, const char *, int);
 static struct machine_function *mips_init_machine_status (void);
 static void print_operand_reloc (FILE *, rtx, const char **);
 #if TARGET_IRIX
@@ -205,6 +330,7 @@ static void mips_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
 static int symbolic_expression_p (rtx);
 static void mips_select_rtx_section (enum machine_mode, rtx,
                                     unsigned HOST_WIDE_INT);
+static void mips_function_rodata_section (tree);
 static bool mips_in_small_data_p (tree);
 static int mips_fpr_return_fields (tree, tree *);
 static bool mips_return_in_msb (tree);
@@ -239,7 +365,7 @@ static void mips_avoid_hazards (void);
 static void mips_reorg (void);
 static bool mips_strict_matching_cpu_name_p (const char *, const char *);
 static bool mips_matching_cpu_name_p (const char *, const char *);
-static const struct mips_cpu_info *mips_parse_cpu (const char *, const char *);
+static const struct mips_cpu_info *mips_parse_cpu (const char *);
 static const struct mips_cpu_info *mips_cpu_info_from_isa (int);
 static bool mips_return_in_memory (tree, tree);
 static bool mips_strict_argument_naming (CUMULATIVE_ARGS *);
@@ -262,16 +388,25 @@ static tree mips_build_builtin_va_list (void);
 static tree mips_gimplify_va_arg_expr (tree, tree, tree *, tree *);
 static bool mips_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode mode,
                                    tree, bool);
+static bool mips_callee_copies (CUMULATIVE_ARGS *, enum machine_mode mode,
+                               tree, bool);
+static int mips_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode mode,
+                                  tree, bool);
+static bool mips_valid_pointer_mode (enum machine_mode);
 static bool mips_vector_mode_supported_p (enum machine_mode);
-static void mips_init_builtins (void);
+static rtx mips_prepare_builtin_arg (enum insn_code, unsigned int, tree *);
+static rtx mips_prepare_builtin_target (enum insn_code, unsigned int, rtx);
 static rtx mips_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
-static rtx mips_expand_compare_builtin (rtx, unsigned int, tree);
-static rtx mips_expand_ps_compare_builtin (enum mips_cmp_choice, rtx,
-                                          unsigned int, tree);
-static rtx mips_expand_4s_compare_builtin (enum mips_cmp_choice, rtx,
-                                          unsigned int, tree);
-static rtx mips_expand_ps_cond_move_builtin (enum mips_cmp_choice, rtx,
-                                            unsigned int, tree);
+static void mips_init_builtins (void);
+static rtx mips_expand_builtin_direct (enum insn_code, rtx, tree, bool);
+static rtx mips_expand_builtin_movtf (enum mips_builtin_type,
+                                     enum insn_code, enum mips_fp_condition,
+                                     rtx, tree);
+static rtx mips_expand_builtin_compare (enum mips_builtin_type,
+                                       enum insn_code, enum mips_fp_condition,
+                                       rtx, tree);
+static rtx mips_expand_builtin_bposge (enum mips_builtin_type, rtx);
+static void mips_encode_section_info (tree, rtx, int);
 
 /* Structure to be filled in by compute_frame_size with register
    save masks, and offsets for the current function.  */
@@ -300,6 +435,10 @@ struct machine_function GTY(()) {
      refers to GP relative global variables.  */
   rtx mips16_gp_pseudo_rtx;
 
+  /* The number of extra stack bytes taken up by register varargs.
+     This area is allocated by the callee at the very top of the frame.  */
+  int varargs_size;
+
   /* Current frame information, calculated by compute_frame_size.  */
   struct mips_frame_info frame;
 
@@ -328,8 +467,12 @@ struct mips_arg_info
   /* The number of words passed in registers, rounded up.  */
   unsigned int reg_words;
 
-  /* The offset of the first register from GP_ARG_FIRST or FP_ARG_FIRST,
-     or MAX_ARGS_IN_REGISTERS if the argument is passed entirely
+  /* For EABI, the offset of the first register from GP_ARG_FIRST or
+     FP_ARG_FIRST.  For other ABIs, the offset of the first register from
+     the start of the ABI's argument structure (see the CUMULATIVE_ARGS
+     comment for details).
+
+     The value is MAX_ARGS_IN_REGISTERS if the argument is passed entirely
      on the stack.  */
   unsigned int reg_offset;
 
@@ -446,13 +589,10 @@ const struct mips_cpu_info *mips_tune_info;
 int mips_isa;
 
 /* Which ABI to use.  */
-int mips_abi;
+int mips_abi = MIPS_ABI_DEFAULT;
 
-/* Strings to hold which cpu and instruction set architecture to use.  */
-const char *mips_arch_string;   /* for -march=<xxx> */
-const char *mips_tune_string;   /* for -mtune=<xxx> */
-const char *mips_isa_string;   /* for -mips{1,2,3,4} */
-const char *mips_abi_string;   /* for -mabi={32,n32,64,eabi} */
+/* Cost information to use.  */
+const struct mips_rtx_cost_data *mips_cost;
 
 /* Whether we are generating mips16 hard float code.  In mips16 mode
    we always set TARGET_SOFT_FLOAT; this variable is nonzero if
@@ -460,7 +600,8 @@ const char *mips_abi_string;        /* for -mabi={32,n32,64,eabi} */
    should arrange to call mips32 hard floating point code.  */
 int mips16_hard_float;
 
-const char *mips_cache_flush_func = CACHE_FLUSH_FUNC;
+/* The architecture selected by -mipsN.  */
+static const struct mips_cpu_info *mips_isa_info;
 
 /* If TRUE, we split addresses into their high and low parts in the RTL.  */
 int mips_split_addresses;
@@ -498,7 +639,7 @@ static const char *mips_hi_relocs[NUM_SYMBOL_TYPES];
 /* Map hard register number to register class */
 const enum reg_class mips_regno_to_class[] =
 {
-  LEA_REGS,    LEA_REGS,       M16_NA_REGS,    M16_NA_REGS,
+  LEA_REGS,    LEA_REGS,       M16_NA_REGS,    V1_REG,
   M16_REGS,    M16_REGS,       M16_REGS,       M16_REGS,
   LEA_REGS,    LEA_REGS,       LEA_REGS,       LEA_REGS,
   LEA_REGS,    LEA_REGS,       LEA_REGS,       LEA_REGS,
@@ -541,11 +682,21 @@ const enum reg_class mips_regno_to_class[] =
   COP3_REGS,   COP3_REGS,      COP3_REGS,      COP3_REGS,
   COP3_REGS,   COP3_REGS,      COP3_REGS,      COP3_REGS,
   COP3_REGS,   COP3_REGS,      COP3_REGS,      COP3_REGS,
-  COP3_REGS,   COP3_REGS,      COP3_REGS,      COP3_REGS
+  COP3_REGS,   COP3_REGS,      COP3_REGS,      COP3_REGS,
+  DSP_ACC_REGS,        DSP_ACC_REGS,   DSP_ACC_REGS,   DSP_ACC_REGS,
+  DSP_ACC_REGS,        DSP_ACC_REGS,   ALL_REGS,       ALL_REGS,
+  ALL_REGS,    ALL_REGS,       ALL_REGS,       ALL_REGS
 };
 
 /* Map register constraint character to register class.  */
 enum reg_class mips_char_to_class[256];
+
+/* Table of machine dependent attributes.  */
+const struct attribute_spec mips_attribute_table[] =
+{
+  { "long_call",   0, 0, false, true,  true,  NULL },
+  { NULL,         0, 0, false, false, false, NULL }
+};
 \f
 /* A table describing all the processors gcc knows about.  Names are
    matched in the order listed.  The first mention of an ISA level is
@@ -593,13 +744,19 @@ const struct mips_cpu_info mips_cpu_info_table[] = {
 
   /* MIPS32 */
   { "4kc", PROCESSOR_4KC, 32 },
-  { "4kp", PROCESSOR_4KC, 32 }, /* = 4kc */
+  { "4km", PROCESSOR_4KC, 32 }, /* = 4kc */
+  { "4kp", PROCESSOR_4KP, 32 },
 
   /* MIPS32 Release 2 */
   { "m4k", PROCESSOR_M4K, 33 },
+  { "24k", PROCESSOR_24K, 33 },
+  { "24kc", PROCESSOR_24K, 33 },  /* 24K  no FPU */
+  { "24kf", PROCESSOR_24K, 33 },  /* 24K 1:2 FPU */
+  { "24kx", PROCESSOR_24KX, 33 }, /* 24K 1:1 FPU */
 
   /* MIPS64 */
   { "5kc", PROCESSOR_5KC, 64 },
+  { "5kf", PROCESSOR_5KF, 64 },
   { "20kc", PROCESSOR_20KC, 64 },
   { "sb1", PROCESSOR_SB1, 64 },
   { "sr71000", PROCESSOR_SR71000, 64 },
@@ -607,6 +764,275 @@ const struct mips_cpu_info mips_cpu_info_table[] = {
   /* End marker */
   { 0, 0, 0 }
 };
+
+/* Default costs. If these are used for a processor we should look
+   up the actual costs.  */
+#define DEFAULT_COSTS COSTS_N_INSNS (6),  /* fp_add */       \
+                      COSTS_N_INSNS (7),  /* fp_mult_sf */   \
+                      COSTS_N_INSNS (8),  /* fp_mult_df */   \
+                      COSTS_N_INSNS (23), /* fp_div_sf */    \
+                      COSTS_N_INSNS (36), /* fp_div_df */    \
+                      COSTS_N_INSNS (10), /* int_mult_si */  \
+                      COSTS_N_INSNS (10), /* int_mult_di */  \
+                      COSTS_N_INSNS (69), /* int_div_si */   \
+                      COSTS_N_INSNS (69), /* int_div_di */   \
+                                       2, /* branch_cost */  \
+                                       4  /* memory_latency */
+
+/* Need to replace these with the costs of calling the appropriate
+   libgcc routine.  */
+#define SOFT_FP_COSTS COSTS_N_INSNS (256), /* fp_add */       \
+                      COSTS_N_INSNS (256), /* fp_mult_sf */   \
+                      COSTS_N_INSNS (256), /* fp_mult_df */   \
+                      COSTS_N_INSNS (256), /* fp_div_sf */    \
+                      COSTS_N_INSNS (256)  /* fp_div_df */
+
+static struct mips_rtx_cost_data const mips_rtx_cost_data[PROCESSOR_MAX] =
+  {
+    { /* R3000 */
+      COSTS_N_INSNS (2),            /* fp_add */
+      COSTS_N_INSNS (4),            /* fp_mult_sf */
+      COSTS_N_INSNS (5),            /* fp_mult_df */
+      COSTS_N_INSNS (12),           /* fp_div_sf */
+      COSTS_N_INSNS (19),           /* fp_div_df */
+      COSTS_N_INSNS (12),           /* int_mult_si */
+      COSTS_N_INSNS (12),           /* int_mult_di */
+      COSTS_N_INSNS (35),           /* int_div_si */
+      COSTS_N_INSNS (35),           /* int_div_di */
+                       1,           /* branch_cost */
+                       4            /* memory_latency */
+
+    },
+    { /* 4KC */
+      SOFT_FP_COSTS,
+      COSTS_N_INSNS (6),            /* int_mult_si */
+      COSTS_N_INSNS (6),            /* int_mult_di */
+      COSTS_N_INSNS (36),           /* int_div_si */
+      COSTS_N_INSNS (36),           /* int_div_di */
+                       1,           /* branch_cost */
+                       4            /* memory_latency */
+    },
+    { /* 4KP */
+      SOFT_FP_COSTS,
+      COSTS_N_INSNS (36),           /* int_mult_si */
+      COSTS_N_INSNS (36),           /* int_mult_di */
+      COSTS_N_INSNS (37),           /* int_div_si */
+      COSTS_N_INSNS (37),           /* int_div_di */
+                       1,           /* branch_cost */
+                       4            /* memory_latency */
+    },
+    { /* 5KC */
+      SOFT_FP_COSTS,
+      COSTS_N_INSNS (4),            /* int_mult_si */
+      COSTS_N_INSNS (11),           /* int_mult_di */
+      COSTS_N_INSNS (36),           /* int_div_si */
+      COSTS_N_INSNS (68),           /* int_div_di */
+                       1,           /* branch_cost */
+                       4            /* memory_latency */
+    },
+    { /* 5KF */
+      COSTS_N_INSNS (4),            /* fp_add */
+      COSTS_N_INSNS (4),            /* fp_mult_sf */
+      COSTS_N_INSNS (5),            /* fp_mult_df */
+      COSTS_N_INSNS (17),           /* fp_div_sf */
+      COSTS_N_INSNS (32),           /* fp_div_df */
+      COSTS_N_INSNS (4),            /* int_mult_si */
+      COSTS_N_INSNS (11),           /* int_mult_di */
+      COSTS_N_INSNS (36),           /* int_div_si */
+      COSTS_N_INSNS (68),           /* int_div_di */
+                       1,           /* branch_cost */
+                       4            /* memory_latency */
+    },
+    { /* 20KC */
+      DEFAULT_COSTS
+    },
+    { /* 24k */
+      COSTS_N_INSNS (8),            /* fp_add */
+      COSTS_N_INSNS (8),            /* fp_mult_sf */
+      COSTS_N_INSNS (10),           /* fp_mult_df */
+      COSTS_N_INSNS (34),           /* fp_div_sf */
+      COSTS_N_INSNS (64),           /* fp_div_df */
+      COSTS_N_INSNS (5),            /* int_mult_si */
+      COSTS_N_INSNS (5),            /* int_mult_di */
+      COSTS_N_INSNS (41),           /* int_div_si */
+      COSTS_N_INSNS (41),           /* int_div_di */
+                       1,           /* branch_cost */
+                       4            /* memory_latency */
+    },
+    { /* 24kx */
+      COSTS_N_INSNS (4),            /* fp_add */
+      COSTS_N_INSNS (4),            /* fp_mult_sf */
+      COSTS_N_INSNS (5),            /* fp_mult_df */
+      COSTS_N_INSNS (17),           /* fp_div_sf */
+      COSTS_N_INSNS (32),           /* fp_div_df */
+      COSTS_N_INSNS (5),            /* int_mult_si */
+      COSTS_N_INSNS (5),            /* int_mult_di */
+      COSTS_N_INSNS (41),           /* int_div_si */
+      COSTS_N_INSNS (41),           /* int_div_di */
+                       1,           /* branch_cost */
+                       4            /* memory_latency */
+    },
+    { /* M4k */
+      DEFAULT_COSTS
+    },
+    { /* R3900 */
+      COSTS_N_INSNS (2),            /* fp_add */
+      COSTS_N_INSNS (4),            /* fp_mult_sf */
+      COSTS_N_INSNS (5),            /* fp_mult_df */
+      COSTS_N_INSNS (12),           /* fp_div_sf */
+      COSTS_N_INSNS (19),           /* fp_div_df */
+      COSTS_N_INSNS (2),            /* int_mult_si */
+      COSTS_N_INSNS (2),            /* int_mult_di */
+      COSTS_N_INSNS (35),           /* int_div_si */
+      COSTS_N_INSNS (35),           /* int_div_di */
+                       1,           /* branch_cost */
+                       4            /* memory_latency */
+    },
+    { /* R6000 */
+      COSTS_N_INSNS (3),            /* fp_add */
+      COSTS_N_INSNS (5),            /* fp_mult_sf */
+      COSTS_N_INSNS (6),            /* fp_mult_df */
+      COSTS_N_INSNS (15),           /* fp_div_sf */
+      COSTS_N_INSNS (16),           /* fp_div_df */
+      COSTS_N_INSNS (17),           /* int_mult_si */
+      COSTS_N_INSNS (17),           /* int_mult_di */
+      COSTS_N_INSNS (38),           /* int_div_si */
+      COSTS_N_INSNS (38),           /* int_div_di */
+                       2,           /* branch_cost */
+                       6            /* memory_latency */
+    },
+    { /* R4000 */
+       COSTS_N_INSNS (6),           /* fp_add */
+       COSTS_N_INSNS (7),           /* fp_mult_sf */
+       COSTS_N_INSNS (8),           /* fp_mult_df */
+       COSTS_N_INSNS (23),          /* fp_div_sf */
+       COSTS_N_INSNS (36),          /* fp_div_df */
+       COSTS_N_INSNS (10),          /* int_mult_si */
+       COSTS_N_INSNS (10),          /* int_mult_di */
+       COSTS_N_INSNS (69),          /* int_div_si */
+       COSTS_N_INSNS (69),          /* int_div_di */
+                        2,          /* branch_cost */
+                        6           /* memory_latency */
+    },
+    { /* R4100 */
+      DEFAULT_COSTS
+    },
+    { /* R4111 */
+      DEFAULT_COSTS
+    },
+    { /* R4120 */
+      DEFAULT_COSTS
+    },
+    { /* R4130 */
+      /* The only costs that appear to be updated here are
+        integer multiplication.  */
+      SOFT_FP_COSTS,
+      COSTS_N_INSNS (4),            /* int_mult_si */
+      COSTS_N_INSNS (6),            /* int_mult_di */
+      COSTS_N_INSNS (69),           /* int_div_si */
+      COSTS_N_INSNS (69),           /* int_div_di */
+                       1,           /* branch_cost */
+                       4            /* memory_latency */
+    },
+    { /* R4300 */
+      DEFAULT_COSTS
+    },
+    { /* R4600 */
+      DEFAULT_COSTS
+    },
+    { /* R4650 */
+      DEFAULT_COSTS
+    },
+    { /* R5000 */
+      COSTS_N_INSNS (6),            /* fp_add */
+      COSTS_N_INSNS (4),            /* fp_mult_sf */
+      COSTS_N_INSNS (5),            /* fp_mult_df */
+      COSTS_N_INSNS (23),           /* fp_div_sf */
+      COSTS_N_INSNS (36),           /* fp_div_df */
+      COSTS_N_INSNS (5),            /* int_mult_si */
+      COSTS_N_INSNS (5),            /* int_mult_di */
+      COSTS_N_INSNS (36),           /* int_div_si */
+      COSTS_N_INSNS (36),           /* int_div_di */
+                       1,           /* branch_cost */
+                       4            /* memory_latency */
+    },
+    { /* R5400 */
+      COSTS_N_INSNS (6),            /* fp_add */
+      COSTS_N_INSNS (5),            /* fp_mult_sf */
+      COSTS_N_INSNS (6),            /* fp_mult_df */
+      COSTS_N_INSNS (30),           /* fp_div_sf */
+      COSTS_N_INSNS (59),           /* fp_div_df */
+      COSTS_N_INSNS (3),            /* int_mult_si */
+      COSTS_N_INSNS (4),            /* int_mult_di */
+      COSTS_N_INSNS (42),           /* int_div_si */
+      COSTS_N_INSNS (74),           /* int_div_di */
+                       1,           /* branch_cost */
+                       4            /* memory_latency */
+    },
+    { /* R5500 */
+      COSTS_N_INSNS (6),            /* fp_add */
+      COSTS_N_INSNS (5),            /* fp_mult_sf */
+      COSTS_N_INSNS (6),            /* fp_mult_df */
+      COSTS_N_INSNS (30),           /* fp_div_sf */
+      COSTS_N_INSNS (59),           /* fp_div_df */
+      COSTS_N_INSNS (5),            /* int_mult_si */
+      COSTS_N_INSNS (9),            /* int_mult_di */
+      COSTS_N_INSNS (42),           /* int_div_si */
+      COSTS_N_INSNS (74),           /* int_div_di */
+                       1,           /* branch_cost */
+                       4            /* memory_latency */
+    },
+    { /* R7000 */
+      /* The only costs that are changed here are
+        integer multiplication.  */
+      COSTS_N_INSNS (6),            /* fp_add */
+      COSTS_N_INSNS (7),            /* fp_mult_sf */
+      COSTS_N_INSNS (8),            /* fp_mult_df */
+      COSTS_N_INSNS (23),           /* fp_div_sf */
+      COSTS_N_INSNS (36),           /* fp_div_df */
+      COSTS_N_INSNS (5),            /* int_mult_si */
+      COSTS_N_INSNS (9),            /* int_mult_di */
+      COSTS_N_INSNS (69),           /* int_div_si */
+      COSTS_N_INSNS (69),           /* int_div_di */
+                       1,           /* branch_cost */
+                       4            /* memory_latency */
+    },
+    { /* R8000 */
+      DEFAULT_COSTS
+    },
+    { /* R9000 */
+      /* The only costs that are changed here are
+        integer multiplication.  */
+      COSTS_N_INSNS (6),            /* fp_add */
+      COSTS_N_INSNS (7),            /* fp_mult_sf */
+      COSTS_N_INSNS (8),            /* fp_mult_df */
+      COSTS_N_INSNS (23),           /* fp_div_sf */
+      COSTS_N_INSNS (36),           /* fp_div_df */
+      COSTS_N_INSNS (3),            /* int_mult_si */
+      COSTS_N_INSNS (8),            /* int_mult_di */
+      COSTS_N_INSNS (69),           /* int_div_si */
+      COSTS_N_INSNS (69),           /* int_div_di */
+                       1,           /* branch_cost */
+                       4            /* memory_latency */
+    },
+    { /* SB1 */
+      COSTS_N_INSNS (4),            /* fp_add */
+      COSTS_N_INSNS (4),            /* fp_mult_sf */
+      COSTS_N_INSNS (4),            /* fp_mult_df */
+      COSTS_N_INSNS (24),           /* fp_div_sf */
+      COSTS_N_INSNS (32),           /* fp_div_df */
+      COSTS_N_INSNS (3),            /* int_mult_si */
+      COSTS_N_INSNS (4),            /* int_mult_di */
+      COSTS_N_INSNS (36),           /* int_div_si */
+      COSTS_N_INSNS (68),           /* int_div_di */
+                       1,           /* branch_cost */
+                       4            /* memory_latency */
+    },
+    { /* SR71000 */
+      DEFAULT_COSTS
+    },
+  };
+
 \f
 /* Nonzero if -march should decide the default value of MASK_SOFT_FLOAT.  */
 #ifndef MIPS_MARCH_CONTROLS_SOFT_FLOAT
@@ -627,6 +1053,8 @@ const struct mips_cpu_info mips_cpu_info_table[] = {
 #define TARGET_ASM_FUNCTION_EPILOGUE mips_output_function_epilogue
 #undef TARGET_ASM_SELECT_RTX_SECTION
 #define TARGET_ASM_SELECT_RTX_SECTION mips_select_rtx_section
+#undef TARGET_ASM_FUNCTION_RODATA_SECTION
+#define TARGET_ASM_FUNCTION_RODATA_SECTION mips_function_rodata_section
 
 #undef TARGET_SCHED_REORDER
 #define TARGET_SCHED_REORDER mips_sched_reorder
@@ -640,6 +1068,17 @@ const struct mips_cpu_info mips_cpu_info_table[] = {
 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
   mips_multipass_dfa_lookahead
 
+#undef TARGET_DEFAULT_TARGET_FLAGS
+#define TARGET_DEFAULT_TARGET_FLAGS            \
+  (TARGET_DEFAULT                              \
+   | TARGET_CPU_DEFAULT                                \
+   | TARGET_ENDIAN_DEFAULT                     \
+   | TARGET_FP_EXCEPTIONS_DEFAULT              \
+   | MASK_CHECK_ZERO_DIV                       \
+   | MASK_FUSED_MADD)
+#undef TARGET_HANDLE_OPTION
+#define TARGET_HANDLE_OPTION mips_handle_option
+
 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
 #define TARGET_FUNCTION_OK_FOR_SIBCALL mips_function_ok_for_sibcall
 
@@ -696,6 +1135,10 @@ const struct mips_cpu_info mips_cpu_info_table[] = {
 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
 #undef TARGET_PASS_BY_REFERENCE
 #define TARGET_PASS_BY_REFERENCE mips_pass_by_reference
+#undef TARGET_CALLEE_COPIES
+#define TARGET_CALLEE_COPIES mips_callee_copies
+#undef TARGET_ARG_PARTIAL_BYTES
+#define TARGET_ARG_PARTIAL_BYTES mips_arg_partial_bytes
 
 #undef TARGET_VECTOR_MODE_SUPPORTED_P
 #define TARGET_VECTOR_MODE_SUPPORTED_P mips_vector_mode_supported_p
@@ -705,6 +1148,18 @@ const struct mips_cpu_info mips_cpu_info_table[] = {
 #undef TARGET_EXPAND_BUILTIN
 #define TARGET_EXPAND_BUILTIN mips_expand_builtin
 
+#undef TARGET_HAVE_TLS
+#define TARGET_HAVE_TLS HAVE_AS_TLS
+
+#undef TARGET_CANNOT_FORCE_CONST_MEM
+#define TARGET_CANNOT_FORCE_CONST_MEM mips_cannot_force_const_mem
+
+#undef TARGET_ENCODE_SECTION_INFO
+#define TARGET_ENCODE_SECTION_INFO mips_encode_section_info
+
+#undef TARGET_ATTRIBUTE_TABLE
+#define TARGET_ATTRIBUTE_TABLE mips_attribute_table
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
 /* Classify symbol X, which must be a SYMBOL_REF or a LABEL_REF.  */
@@ -721,8 +1176,10 @@ mips_classify_symbol (rtx x)
       return SYMBOL_GENERAL;
     }
 
-  if (GET_CODE (x) != SYMBOL_REF)
-    abort ();
+  gcc_assert (GET_CODE (x) == SYMBOL_REF);
+
+  if (SYMBOL_REF_TLS_MODEL (x))
+    return SYMBOL_TLS;
 
   if (CONSTANT_POOL_ADDRESS_P (x))
     {
@@ -832,7 +1289,11 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
   if (UNSPEC_ADDRESS_P (x))
     *symbol_type = UNSPEC_ADDRESS_TYPE (x);
   else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
-    *symbol_type = mips_classify_symbol (x);
+    {
+      *symbol_type = mips_classify_symbol (x);
+      if (*symbol_type == SYMBOL_TLS)
+       return false;
+    }
   else
     return false;
 
@@ -882,9 +1343,15 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
     case SYMBOL_GOTOFF_GLOBAL:
     case SYMBOL_GOTOFF_CALL:
     case SYMBOL_GOTOFF_LOADGP:
+    case SYMBOL_TLSGD:
+    case SYMBOL_TLSLDM:
+    case SYMBOL_DTPREL:
+    case SYMBOL_TPREL:
+    case SYMBOL_GOTTPREL:
+    case SYMBOL_TLS:
       return false;
     }
-  abort ();
+  gcc_unreachable ();
 }
 
 
@@ -948,7 +1415,7 @@ mips_valid_base_register_p (rtx x, enum machine_mode mode, int strict)
   if (!strict && GET_CODE (x) == SUBREG)
     x = SUBREG_REG (x);
 
-  return (GET_CODE (x) == REG
+  return (REG_P (x)
          && mips_regno_mode_ok_for_base_p (REGNO (x), mode, strict));
 }
 
@@ -979,6 +1446,14 @@ mips_symbolic_address_p (enum mips_symbol_type symbol_type,
       /* The address will have to be loaded from the GOT first.  */
       return false;
 
+    case SYMBOL_TLSGD:
+    case SYMBOL_TLSLDM:
+    case SYMBOL_DTPREL:
+    case SYMBOL_TPREL:
+    case SYMBOL_GOTTPREL:
+    case SYMBOL_TLS:
+      return false;
+
     case SYMBOL_GOTOFF_PAGE:
     case SYMBOL_GOTOFF_GLOBAL:
     case SYMBOL_GOTOFF_CALL:
@@ -988,7 +1463,7 @@ mips_symbolic_address_p (enum mips_symbol_type symbol_type,
     case SYMBOL_64_LOW:
       return true;
     }
-  abort ();
+  gcc_unreachable ();
 }
 
 
@@ -1043,6 +1518,33 @@ mips_classify_address (struct mips_address_info *info, rtx x,
       return false;
     }
 }
+
+/* Return true if X is a thread-local symbol.  */
+
+static bool
+mips_tls_operand_p (rtx x)
+{
+  return GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0;
+}
+
+/* Return true if X can not be forced into a constant pool.  */
+
+static int
+mips_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
+{
+  return mips_tls_operand_p (*x);
+}
+
+/* Return true if X can not be forced into a constant pool.  */
+
+static bool
+mips_cannot_force_const_mem (rtx x)
+{
+  if (! TARGET_HAVE_TLS)
+    return false;
+
+  return for_each_rtx (&x, &mips_tls_symbol_ref_1, 0);
+}
 \f
 /* Return the number of instructions needed to load a symbol of the
    given type into a register.  If valid in an address, the same number
@@ -1112,10 +1614,19 @@ mips_symbol_insns (enum mips_symbol_type type)
     case SYMBOL_64_HIGH:
     case SYMBOL_64_MID:
     case SYMBOL_64_LOW:
+    case SYMBOL_TLSGD:
+    case SYMBOL_TLSLDM:
+    case SYMBOL_DTPREL:
+    case SYMBOL_GOTTPREL:
+    case SYMBOL_TPREL:
       /* Check whether the offset is a 16- or 32-bit value.  */
       return mips_split_p[type] ? 2 : 1;
+
+    case SYMBOL_TLS:
+      /* We don't treat a bare TLS symbol as a constant.  */
+      return 0;
     }
-  abort ();
+  gcc_unreachable ();
 }
 
 /* Return true if X is a legitimate $sp-based address for mode MDOE.  */
@@ -1273,9 +1784,7 @@ mips_const_insns (rtx x)
 int
 mips_fetch_insns (rtx x)
 {
-  if (GET_CODE (x) != MEM)
-    abort ();
-
+  gcc_assert (MEM_P (x));
   return mips_address_insns (XEXP (x, 0), GET_MODE (x));
 }
 
@@ -1289,7 +1798,13 @@ mips_idiv_insns (void)
 
   count = 1;
   if (TARGET_CHECK_ZERO_DIV)
-    count += 2;
+    {
+      if (GENERATE_DIVIDE_TRAPS)
+        count++;
+      else
+        count += 2;
+    }
+
   if (TARGET_FIX_R4000 || TARGET_FIX_R4400)
     count++;
   return count;
@@ -1406,6 +1921,114 @@ mips_add_offset (rtx temp, rtx reg, HOST_WIDE_INT offset)
   return plus_constant (reg, offset);
 }
 
+/* Emit a call to __tls_get_addr.  SYM is the TLS symbol we are
+   referencing, and TYPE is the symbol type to use (either global
+   dynamic or local dynamic).  V0 is an RTX for the return value
+   location.  The entire insn sequence is returned.  */
+
+static GTY(()) rtx mips_tls_symbol;
+
+static rtx
+mips_call_tls_get_addr (rtx sym, enum mips_symbol_type type, rtx v0)
+{
+  rtx insn, loc, tga, a0;
+
+  a0 = gen_rtx_REG (Pmode, GP_ARG_FIRST);
+
+  if (!mips_tls_symbol)
+    mips_tls_symbol = init_one_libfunc ("__tls_get_addr");
+
+  loc = mips_unspec_address (sym, type);
+
+  start_sequence ();
+
+  emit_insn (gen_rtx_SET (Pmode, a0,
+                         gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, loc)));
+  tga = gen_rtx_MEM (Pmode, mips_tls_symbol);
+  insn = emit_call_insn (gen_call_value (v0, tga, const0_rtx, const0_rtx));
+  CONST_OR_PURE_CALL_P (insn) = 1;
+  use_reg (&CALL_INSN_FUNCTION_USAGE (insn), v0);
+  use_reg (&CALL_INSN_FUNCTION_USAGE (insn), a0);
+  insn = get_insns ();
+
+  end_sequence ();
+
+  return insn;
+}
+
+/* Generate the code to access LOC, a thread local SYMBOL_REF.  The
+   return value will be a valid address and move_operand (either a REG
+   or a LO_SUM).  */
+
+static rtx
+mips_legitimize_tls_address (rtx loc)
+{
+  rtx dest, insn, v0, v1, tmp1, tmp2, eqv;
+  enum tls_model model;
+
+  v0 = gen_rtx_REG (Pmode, GP_RETURN);
+  v1 = gen_rtx_REG (Pmode, GP_RETURN + 1);
+
+  model = SYMBOL_REF_TLS_MODEL (loc);
+
+  switch (model)
+    {
+    case TLS_MODEL_GLOBAL_DYNAMIC:
+      insn = mips_call_tls_get_addr (loc, SYMBOL_TLSGD, v0);
+      dest = gen_reg_rtx (Pmode);
+      emit_libcall_block (insn, dest, v0, loc);
+      break;
+
+    case TLS_MODEL_LOCAL_DYNAMIC:
+      insn = mips_call_tls_get_addr (loc, SYMBOL_TLSLDM, v0);
+      tmp1 = gen_reg_rtx (Pmode);
+
+      /* Attach a unique REG_EQUIV, to allow the RTL optimizers to
+        share the LDM result with other LD model accesses.  */
+      eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
+                           UNSPEC_TLS_LDM);
+      emit_libcall_block (insn, tmp1, v0, eqv);
+
+      tmp2 = mips_unspec_offset_high (NULL, tmp1, loc, SYMBOL_DTPREL);
+      dest = gen_rtx_LO_SUM (Pmode, tmp2,
+                            mips_unspec_address (loc, SYMBOL_DTPREL));
+      break;
+
+    case TLS_MODEL_INITIAL_EXEC:
+      tmp1 = gen_reg_rtx (Pmode);
+      tmp2 = mips_unspec_address (loc, SYMBOL_GOTTPREL);
+      if (Pmode == DImode)
+       {
+         emit_insn (gen_tls_get_tp_di (v1));
+         emit_insn (gen_load_gotdi (tmp1, pic_offset_table_rtx, tmp2));
+       }
+      else
+       {
+         emit_insn (gen_tls_get_tp_si (v1));
+         emit_insn (gen_load_gotsi (tmp1, pic_offset_table_rtx, tmp2));
+       }
+      dest = gen_reg_rtx (Pmode);
+      emit_insn (gen_add3_insn (dest, tmp1, v1));
+      break;
+
+    case TLS_MODEL_LOCAL_EXEC:
+
+      if (Pmode == DImode)
+       emit_insn (gen_tls_get_tp_di (v1));
+      else
+       emit_insn (gen_tls_get_tp_si (v1));
+
+      tmp1 = mips_unspec_offset_high (NULL, v1, loc, SYMBOL_TPREL);
+      dest = gen_rtx_LO_SUM (Pmode, tmp1,
+                            mips_unspec_address (loc, SYMBOL_TPREL));
+      break;
+
+    default:
+      gcc_unreachable ();
+    }
+
+  return dest;
+}
 
 /* This function is used to implement LEGITIMIZE_ADDRESS.  If *XLOC can
    be legitimized in a way that the generic machinery might not expect,
@@ -1417,6 +2040,12 @@ mips_legitimize_address (rtx *xloc, enum machine_mode mode)
 {
   enum mips_symbol_type symbol_type;
 
+  if (mips_tls_operand_p (*xloc))
+    {
+      *xloc = mips_legitimize_tls_address (*xloc);
+      return true;
+    }
+
   /* See if the address can split into a high part and a LO_SUM.  */
   if (mips_symbolic_constant_p (*xloc, &symbol_type)
       && mips_symbolic_address_p (symbol_type, mode)
@@ -1592,6 +2221,12 @@ mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src)
       return;
     }
 
+  if (mips_tls_operand_p (src))
+    {
+      emit_move_insn (dest, mips_legitimize_tls_address (src));
+      return;
+    }
+
   /* See if the symbol can be split.  For mips16, this is often worse than
      forcing it in the constant pool since it needs the single-register form
      of addiu or daddiu.  */
@@ -1780,75 +2415,78 @@ static bool
 mips_rtx_costs (rtx x, int code, int outer_code, int *total)
 {
   enum machine_mode mode = GET_MODE (x);
+  bool float_mode_p = FLOAT_MODE_P (mode);
 
   switch (code)
     {
     case CONST_INT:
-      if (!TARGET_MIPS16)
-        {
-          /* Always return 0, since we don't have different sized
-             instructions, hence different costs according to Richard
-             Kenner */
-          *total = 0;
-          return true;
-        }
-
-      /* A number between 1 and 8 inclusive is efficient for a shift.
-         Otherwise, we will need an extended instruction.  */
-      if ((outer_code) == ASHIFT || (outer_code) == ASHIFTRT
-          || (outer_code) == LSHIFTRT)
+      if (TARGET_MIPS16)
         {
-          if (INTVAL (x) >= 1 && INTVAL (x) <= 8)
-            *total = 0;
-          else
-            *total = COSTS_N_INSNS (1);
-          return true;
-        }
+         /* A number between 1 and 8 inclusive is efficient for a shift.
+            Otherwise, we will need an extended instruction.  */
+         if ((outer_code) == ASHIFT || (outer_code) == ASHIFTRT
+             || (outer_code) == LSHIFTRT)
+           {
+             if (INTVAL (x) >= 1 && INTVAL (x) <= 8)
+               *total = 0;
+             else
+               *total = COSTS_N_INSNS (1);
+             return true;
+           }
 
-      /* We can use cmpi for an xor with an unsigned 16 bit value.  */
-      if ((outer_code) == XOR
-          && INTVAL (x) >= 0 && INTVAL (x) < 0x10000)
-        {
-          *total = 0;
-          return true;
-        }
+         /* We can use cmpi for an xor with an unsigned 16 bit value.  */
+         if ((outer_code) == XOR
+             && INTVAL (x) >= 0 && INTVAL (x) < 0x10000)
+           {
+             *total = 0;
+             return true;
+           }
 
-      /* We may be able to use slt or sltu for a comparison with a
-         signed 16 bit value.  (The boundary conditions aren't quite
-         right, but this is just a heuristic anyhow.)  */
-      if (((outer_code) == LT || (outer_code) == LE
-           || (outer_code) == GE || (outer_code) == GT
-           || (outer_code) == LTU || (outer_code) == LEU
-           || (outer_code) == GEU || (outer_code) == GTU)
-          && INTVAL (x) >= -0x8000 && INTVAL (x) < 0x8000)
-        {
-          *total = 0;
-          return true;
-        }
+         /* We may be able to use slt or sltu for a comparison with a
+            signed 16 bit value.  (The boundary conditions aren't quite
+            right, but this is just a heuristic anyhow.)  */
+         if (((outer_code) == LT || (outer_code) == LE
+              || (outer_code) == GE || (outer_code) == GT
+              || (outer_code) == LTU || (outer_code) == LEU
+              || (outer_code) == GEU || (outer_code) == GTU)
+             && INTVAL (x) >= -0x8000 && INTVAL (x) < 0x8000)
+           {
+             *total = 0;
+             return true;
+           }
 
-      /* Equality comparisons with 0 are cheap.  */
-      if (((outer_code) == EQ || (outer_code) == NE)
-          && INTVAL (x) == 0)
-        {
-          *total = 0;
-          return true;
-        }
+         /* Equality comparisons with 0 are cheap.  */
+         if (((outer_code) == EQ || (outer_code) == NE)
+             && INTVAL (x) == 0)
+           {
+             *total = 0;
+             return true;
+           }
 
-      /* Constants in the range 0...255 can be loaded with an unextended
-        instruction.  They are therefore as cheap as a register move.
+         /* Constants in the range 0...255 can be loaded with an unextended
+            instruction.  They are therefore as cheap as a register move.
 
-        Given the choice between "li R1,0...255" and "move R1,R2"
-        (where R2 is a known constant), it is usually better to use "li",
-        since we do not want to unnessarily extend the lifetime of R2.  */
-      if (outer_code == SET
-         && INTVAL (x) >= 0
-         && INTVAL (x) < 256)
+            Given the choice between "li R1,0...255" and "move R1,R2"
+            (where R2 is a known constant), it is usually better to use "li",
+            since we do not want to unnecessarily extend the lifetime
+            of R2.  */
+         if (outer_code == SET
+             && INTVAL (x) >= 0
+             && INTVAL (x) < 256)
+           {
+             *total = 0;
+             return true;
+           }
+       }
+      else
        {
+         /* These can be used anywhere. */
          *total = 0;
          return true;
        }
 
-      /* Otherwise fall through to the handling below.  */
+      /* Otherwise fall through to the handling below because
+        we'll need to construct the constant.  */
 
     case CONST:
     case SYMBOL_REF:
@@ -1868,15 +2506,15 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
 
     case MEM:
       {
-        /* If the address is legitimate, return the number of
-           instructions it needs, otherwise use the default handling.  */
-        int n = mips_address_insns (XEXP (x, 0), GET_MODE (x));
-        if (n > 0)
-          {
-            *total = COSTS_N_INSNS (1 + n);
-            return true;
-          }
-        return false;
+       /* If the address is legitimate, return the number of
+          instructions it needs, otherwise use the default handling.  */
+       int n = mips_address_insns (XEXP (x, 0), GET_MODE (x));
+       if (n > 0)
+         {
+           *total = COSTS_N_INSNS (n + 1);
+           return true;
+         }
+       return false;
       }
 
     case FFS:
@@ -1909,7 +2547,7 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
       return false;
 
     case ABS:
-      if (mode == SFmode || mode == DFmode)
+      if (float_mode_p)
         *total = COSTS_N_INSNS (1);
       else
         *total = COSTS_N_INSNS (4);
@@ -1921,19 +2559,13 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
 
     case PLUS:
     case MINUS:
-      if (mode == SFmode || mode == DFmode)
-        {
-          if (TUNE_MIPS3000 || TUNE_MIPS3900)
-            *total = COSTS_N_INSNS (2);
-          else if (TUNE_MIPS6000)
-            *total = COSTS_N_INSNS (3);
-         else if (TUNE_SB1)
-           *total = COSTS_N_INSNS (4);
-          else
-            *total = COSTS_N_INSNS (6);
-          return true;
-        }
-      if (mode == DImode && !TARGET_64BIT)
+      if (float_mode_p)
+       {
+         *total = mips_cost->fp_add;
+         return true;
+       }
+
+      else if (mode == DImode && !TARGET_64BIT)
         {
           *total = COSTS_N_INSNS (4);
           return true;
@@ -1943,115 +2575,46 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
     case NEG:
       if (mode == DImode && !TARGET_64BIT)
         {
-          *total = 4;
+          *total = COSTS_N_INSNS (4);
           return true;
         }
       return false;
 
     case MULT:
       if (mode == SFmode)
-        {
-          if (TUNE_MIPS3000
-              || TUNE_MIPS3900
-              || TUNE_MIPS5000
-             || TUNE_SB1)
-            *total = COSTS_N_INSNS (4);
-          else if (TUNE_MIPS6000
-                   || TUNE_MIPS5400
-                   || TUNE_MIPS5500)
-            *total = COSTS_N_INSNS (5);
-          else
-            *total = COSTS_N_INSNS (7);
-          return true;
-        }
+       *total = mips_cost->fp_mult_sf;
 
-      if (mode == DFmode)
-        {
-          if (TUNE_SB1)
-           *total = COSTS_N_INSNS (4);
-          else if (TUNE_MIPS3000
-              || TUNE_MIPS3900
-              || TUNE_MIPS5000)
-            *total = COSTS_N_INSNS (5);
-          else if (TUNE_MIPS6000
-                   || TUNE_MIPS5400
-                   || TUNE_MIPS5500)
-            *total = COSTS_N_INSNS (6);
-          else
-            *total = COSTS_N_INSNS (8);
-          return true;
-        }
+      else if (mode == DFmode)
+       *total = mips_cost->fp_mult_df;
+
+      else if (mode == SImode)
+       *total = mips_cost->int_mult_si;
 
-      if (TUNE_MIPS3000)
-        *total = COSTS_N_INSNS (12);
-      else if (TUNE_MIPS3900)
-        *total = COSTS_N_INSNS (2);
-      else if (TUNE_MIPS4130)
-       *total = COSTS_N_INSNS (mode == DImode ? 6 : 4);
-      else if (TUNE_MIPS5400 || TUNE_SB1)
-        *total = COSTS_N_INSNS (mode == DImode ? 4 : 3);
-      else if (TUNE_MIPS5500 || TUNE_MIPS7000)
-        *total = COSTS_N_INSNS (mode == DImode ? 9 : 5);
-      else if (TUNE_MIPS9000)
-        *total = COSTS_N_INSNS (mode == DImode ? 8 : 3);
-      else if (TUNE_MIPS6000)
-        *total = COSTS_N_INSNS (17);
-      else if (TUNE_MIPS5000)
-        *total = COSTS_N_INSNS (5);
       else
-        *total = COSTS_N_INSNS (10);
+       *total = mips_cost->int_mult_di;
+
       return true;
 
     case DIV:
     case MOD:
-      if (mode == SFmode)
-        {
-          if (TUNE_MIPS3000
-              || TUNE_MIPS3900)
-            *total = COSTS_N_INSNS (12);
-          else if (TUNE_MIPS6000)
-            *total = COSTS_N_INSNS (15);
-         else if (TUNE_SB1)
-           *total = COSTS_N_INSNS (24);
-          else if (TUNE_MIPS5400 || TUNE_MIPS5500)
-            *total = COSTS_N_INSNS (30);
-          else
-            *total = COSTS_N_INSNS (23);
-          return true;
-        }
+      if (float_mode_p)
+       {
+         if (mode == SFmode)
+           *total = mips_cost->fp_div_sf;
+         else
+           *total = mips_cost->fp_div_df;
 
-      if (mode == DFmode)
-        {
-          if (TUNE_MIPS3000
-              || TUNE_MIPS3900)
-            *total = COSTS_N_INSNS (19);
-          else if (TUNE_MIPS5400 || TUNE_MIPS5500)
-            *total = COSTS_N_INSNS (59);
-          else if (TUNE_MIPS6000)
-            *total = COSTS_N_INSNS (16);
-         else if (TUNE_SB1)
-           *total = COSTS_N_INSNS (32);
-          else
-            *total = COSTS_N_INSNS (36);
-          return true;
-        }
+         return true;
+       }
       /* Fall through.  */
 
     case UDIV:
     case UMOD:
-      if (TUNE_MIPS3000
-          || TUNE_MIPS3900)
-        *total = COSTS_N_INSNS (35);
-      else if (TUNE_MIPS6000)
-        *total = COSTS_N_INSNS (38);
-      else if (TUNE_MIPS5000)
-        *total = COSTS_N_INSNS (36);
-      else if (TUNE_SB1)
-       *total = COSTS_N_INSNS ((mode == SImode) ? 36 : 68);
-      else if (TUNE_MIPS5400 || TUNE_MIPS5500)
-        *total = COSTS_N_INSNS ((mode == SImode) ? 42 : 74);
+      if (mode == DImode)
+        *total = mips_cost->int_div_di;
       else
-        *total = COSTS_N_INSNS (69);
+       *total = mips_cost->int_div_si;
+
       return true;
 
     case SIGN_EXTEND:
@@ -2073,6 +2636,15 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
         *total = COSTS_N_INSNS (1);
       return true;
 
+    case FLOAT:
+    case UNSIGNED_FLOAT:
+    case FIX:
+    case FLOAT_EXTEND:
+    case FLOAT_TRUNCATE:
+    case SQRT:
+      *total = mips_cost->fp_add;
+      return true;
+
     default:
       return false;
     }
@@ -2106,15 +2678,15 @@ mips_subword (rtx op, int high_p)
   else
     byte = 0;
 
-  if (GET_CODE (op) == REG)
+  if (REG_P (op))
     {
       if (FP_REG_P (REGNO (op)))
        return gen_rtx_REG (word_mode, high_p ? REGNO (op) + 1 : REGNO (op));
-      if (REGNO (op) == HI_REGNUM)
-       return gen_rtx_REG (word_mode, high_p ? HI_REGNUM : LO_REGNUM);
+      if (ACC_HI_REG_P (REGNO (op)))
+       return gen_rtx_REG (word_mode, high_p ? REGNO (op) : REGNO (op) + 1);
     }
 
-  if (GET_CODE (op) == MEM)
+  if (MEM_P (op))
     return mips_rewrite_small_data (adjust_address (op, word_mode, byte));
 
   return simplify_gen_subreg (word_mode, op, mode, byte);
@@ -2137,9 +2709,9 @@ mips_split_64bit_move_p (rtx dest, rtx src)
      ldc1 and sdc1 on MIPS II and above.  */
   if (mips_isa > 1)
     {
-      if (FP_REG_RTX_P (dest) && GET_CODE (src) == MEM)
+      if (FP_REG_RTX_P (dest) && MEM_P (src))
        return false;
-      if (FP_REG_RTX_P (src) && GET_CODE (dest) == MEM)
+      if (FP_REG_RTX_P (src) && MEM_P (dest))
        return false;
     }
   return true;
@@ -2184,7 +2756,7 @@ mips_split_64bit_move (rtx dest, rtx src)
       rtx low_dest;
 
       low_dest = mips_subword (dest, 0);
-      if (GET_CODE (low_dest) == REG
+      if (REG_P (low_dest)
          && reg_overlap_mentioned_p (low_dest, src))
        {
          emit_move_insn (mips_subword (dest, 1), mips_subword (src, 1));
@@ -2225,6 +2797,14 @@ mips_output_move (rtx dest, rtx src)
          if (MD_REG_P (REGNO (dest)))
            return "mt%0\t%z1";
 
+         if (DSP_ACC_REG_P (REGNO (dest)))
+           {
+             static char retval[] = "mt__\t%z1,%q0";
+             retval[2] = reg_names[REGNO (dest)][4];
+             retval[3] = reg_names[REGNO (dest)][5];
+             return retval;
+           }
+
          if (FP_REG_P (REGNO (dest)))
            return (dbl_p ? "dmtc1\t%z1,%0" : "mtc1\t%z1,%0");
 
@@ -2243,6 +2823,14 @@ mips_output_move (rtx dest, rtx src)
     {
       if (src_code == REG)
        {
+         if (DSP_ACC_REG_P (REGNO (src)))
+           {
+             static char retval[] = "mf__\t%0,%q1";
+             retval[2] = reg_names[REGNO (src)][4];
+             retval[3] = reg_names[REGNO (src)][5];
+             return retval;
+           }
+
          if (ST_REG_P (REGNO (src)) && ISA_HAS_8CC)
            return "lui\t%0,0x3f80\n\tmovf\t%0,%.,%1";
 
@@ -2318,7 +2906,7 @@ mips_output_move (rtx dest, rtx src)
       retval[3] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (src));
       return retval;
     }
-  abort ();
+  gcc_unreachable ();
 }
 \f
 /* Restore $gp from its save slot.  Valid only when using o32 or
@@ -2329,8 +2917,7 @@ mips_restore_gp (void)
 {
   rtx address, slot;
 
-  if (!TARGET_ABICALLS || !TARGET_OLDABI)
-    abort ();
+  gcc_assert (TARGET_ABICALLS && TARGET_OLDABI);
 
   address = mips_add_offset (pic_offset_table_rtx,
                             frame_pointer_needed
@@ -2380,10 +2967,54 @@ mips_relational_operand_ok_p (enum rtx_code code, rtx cmp1)
       return sleu_operand (cmp1, VOIDmode);
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 }
 
+/* Canonicalize LE or LEU comparisons into LT comparisons when
+   possible to avoid extra instructions or inverting the
+   comparison.  */
+
+static bool
+mips_canonicalize_comparison (enum rtx_code *code, rtx *cmp1, 
+                             enum machine_mode mode)
+{
+  HOST_WIDE_INT original, plus_one;
+
+  if (GET_CODE (*cmp1) != CONST_INT)
+    return false;
+  
+  original = INTVAL (*cmp1);
+  plus_one = trunc_int_for_mode ((unsigned HOST_WIDE_INT) original + 1, mode);
+  
+  switch (*code)
+    {
+    case LE:
+      if (original < plus_one)
+       {
+         *code = LT;
+         *cmp1 = force_reg (mode, GEN_INT (plus_one));
+         return true;
+       }
+      break;
+      
+    case LEU:
+      if (plus_one != 0)
+       {
+         *code = LTU;
+         *cmp1 = force_reg (mode, GEN_INT (plus_one));
+         return true;
+       }
+      break;
+      
+    default:
+      return false;
+   }
+  
+  return false;
+
+}
+
 /* Compare CMP0 and CMP1 using relational operator CODE and store the
    result in TARGET.  CMP0 and TARGET are register_operands that have
    the same integer mode.  If INVERT_PTR is nonnull, it's OK to set
@@ -2394,11 +3025,14 @@ mips_emit_int_relational (enum rtx_code code, bool *invert_ptr,
                          rtx target, rtx cmp0, rtx cmp1)
 {
   /* First see if there is a MIPS instruction that can do this operation
-     with CMP1 in its current form.  If not, try doing the same for the
+     with CMP1 in its current form. If not, try to canonicalize the
+     comparison to LT. If that fails, try doing the same for the
      inverse operation.  If that also fails, force CMP1 into a register
      and try again.  */
   if (mips_relational_operand_ok_p (code, cmp1))
     mips_emit_binary (code, target, cmp0, cmp1);
+  else if (mips_canonicalize_comparison (&code, &cmp1, GET_MODE (target)))
+    mips_emit_binary (code, target, cmp0, cmp1);
   else
     {
       enum rtx_code inv_code = reverse_condition (code);
@@ -2498,8 +3132,6 @@ mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p)
       switch (*code)
        {
        case NE:
-       case UNGE:
-       case UNGT:
        case LTGT:
        case ORDERED:
          cmp_code = reverse_condition_maybe_unordered (*code);
@@ -2727,9 +3359,9 @@ mips_emit_fcc_reload (rtx dest, rtx src, rtx scratch)
   rtx fp1, fp2;
 
   /* Change the source to SFmode.  */
-  if (GET_CODE (src) == MEM)
+  if (MEM_P (src))
     src = adjust_address (src, SFmode, 0);
-  else if (GET_CODE (src) == REG || GET_CODE (src) == SUBREG)
+  else if (REG_P (src) || GET_CODE (src) == SUBREG)
     src = gen_rtx_REG (SFmode, true_regnum (src));
 
   fp1 = gen_rtx_REG (SFmode, REGNO (scratch));
@@ -2750,8 +3382,7 @@ mips_set_return_address (rtx address, rtx scratch)
   rtx slot_address;
 
   compute_frame_size (get_frame_size ());
-  if (((cfun->machine->frame.mask >> 31) & 1) == 0)
-    abort ();
+  gcc_assert ((cfun->machine->frame.mask >> 31) & 1);
   slot_address = mips_add_offset (scratch, stack_pointer_rtx,
                                  cfun->machine->frame.gp_sp_offset);
 
@@ -2798,7 +3429,7 @@ mips_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length)
        {
          rtx part = adjust_address (src, BLKmode, offset);
          if (!mips_expand_unaligned_load (regs[i], part, bits, 0))
-           abort ();
+           gcc_unreachable ();
        }
     }
 
@@ -2810,7 +3441,7 @@ mips_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length)
       {
        rtx part = adjust_address (dest, BLKmode, offset);
        if (!mips_expand_unaligned_store (part, regs[i], bits, 0))
-         abort ();
+         gcc_unreachable ();
       }
 
   /* Mop up any left-over bytes.  */
@@ -2952,7 +3583,7 @@ static void
 mips_arg_info (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
               tree type, int named, struct mips_arg_info *info)
 {
-  bool even_reg_p;
+  bool doubleword_aligned_p;
   unsigned int num_bytes, num_words, max_regs;
 
   /* Work out the size of the argument.  */
@@ -3026,30 +3657,11 @@ mips_arg_info (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
       break;
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
-  /* Now decide whether the argument must go in an even-numbered register.
-     Usually this is determined by type alignment, but there are two
-     exceptions:
-
-     - Under the O64 ABI, the second float argument goes in $f14 if it
-       is single precision (doubles go in $f13 as expected).
-
-     - Floats passed in FPRs must be in an even-numbered register if
-       we're using paired FPRs.  */
-  if (type)
-    even_reg_p = TYPE_ALIGN (type) > BITS_PER_WORD;
-  else
-    even_reg_p = GET_MODE_UNIT_SIZE (mode) > UNITS_PER_WORD;
-
-  if (info->fpr_p)
-    {
-      if (mips_abi == ABI_O64 && mode == SFmode)
-       even_reg_p = true;
-      if (FP_INC > 1)
-       even_reg_p = true;
-    }
+  /* See whether the argument has doubleword alignment.  */
+  doubleword_aligned_p = FUNCTION_ARG_BOUNDARY (mode, type) > BITS_PER_WORD;
 
   /* Set REG_OFFSET to the register count we're interested in.
      The EABI allocates the floating-point registers separately,
@@ -3058,12 +3670,13 @@ mips_arg_info (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
                      ? cum->num_fprs
                      : cum->num_gprs);
 
-  if (even_reg_p)
+  /* Advance to an even register if the argument is doubleword-aligned.  */
+  if (doubleword_aligned_p)
     info->reg_offset += info->reg_offset & 1;
 
-  /* The alignment applied to registers is also applied to stack arguments.  */
+  /* Work out the offset of a stack argument.  */
   info->stack_offset = cum->stack_words;
-  if (even_reg_p)
+  if (doubleword_aligned_p)
     info->stack_offset += info->stack_offset & 1;
 
   max_regs = MAX_ARGS_IN_REGISTERS - info->reg_offset;
@@ -3217,26 +3830,47 @@ function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
       return gen_rtx_PARALLEL (mode, gen_rtvec (2, real, imag));
     }
 
-  if (info.fpr_p)
-    return gen_rtx_REG (mode, FP_ARG_FIRST + info.reg_offset);
-  else
+  if (!info.fpr_p)
     return gen_rtx_REG (mode, GP_ARG_FIRST + info.reg_offset);
+  else if (info.reg_offset == 1)
+    /* This code handles the special o32 case in which the second word
+       of the argument structure is passed in floating-point registers.  */
+    return gen_rtx_REG (mode, FP_ARG_FIRST + FP_INC);
+  else
+    return gen_rtx_REG (mode, FP_ARG_FIRST + info.reg_offset);
 }
 
 
-/* Implement FUNCTION_ARG_PARTIAL_NREGS.  */
+/* Implement TARGET_ARG_PARTIAL_BYTES.  */
 
-int
-function_arg_partial_nregs (const CUMULATIVE_ARGS *cum,
-                           enum machine_mode mode, tree type, int named)
+static int
+mips_arg_partial_bytes (CUMULATIVE_ARGS *cum,
+                       enum machine_mode mode, tree type, bool named)
 {
   struct mips_arg_info info;
 
   mips_arg_info (cum, mode, type, named, &info);
-  return info.stack_words > 0 ? info.reg_words : 0;
+  return info.stack_words > 0 ? info.reg_words * UNITS_PER_WORD : 0;
 }
 
 
+/* Implement FUNCTION_ARG_BOUNDARY.  Every parameter gets at least
+   PARM_BOUNDARY bits of alignment, but will be given anything up
+   to STACK_BOUNDARY bits if the type requires it.  */
+
+int
+function_arg_boundary (enum machine_mode mode, tree type)
+{
+  unsigned int alignment;
+
+  alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode);
+  if (alignment < PARM_BOUNDARY)
+    alignment = PARM_BOUNDARY;
+  if (alignment > STACK_BOUNDARY)
+    alignment = STACK_BOUNDARY;
+  return alignment;
+}
+
 /* Return true if FUNCTION_ARG_PADDING (MODE, TYPE) should return
    upward rather than downward.  In other words, return true if the
    first byte of the stack slot has useful data, false if the last
@@ -3292,7 +3926,8 @@ mips_pad_reg_upward (enum machine_mode mode, tree type)
 \f
 static void
 mips_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
-                            tree type, int *pretend_size, int no_rtl)
+                            tree type, int *pretend_size ATTRIBUTE_UNUSED,
+                            int no_rtl)
 {
   CUMULATIVE_ARGS local_cum;
   int gp_saved, fp_saved;
@@ -3316,18 +3951,9 @@ mips_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
        {
          rtx ptr, mem;
 
-         ptr = virtual_incoming_args_rtx;
-         switch (mips_abi)
-           {
-           case ABI_32:
-           case ABI_O64:
-             ptr = plus_constant (ptr, local_cum.num_gprs * UNITS_PER_WORD);
-             break;
-
-           case ABI_EABI:
-             ptr = plus_constant (ptr, -gp_saved * UNITS_PER_WORD);
-             break;
-           }
+         ptr = plus_constant (virtual_incoming_args_rtx,
+                              REG_PARM_STACK_SPACE (cfun->decl)
+                              - gp_saved * UNITS_PER_WORD);
          mem = gen_rtx_MEM (BLKmode, ptr);
          set_mem_alias_set (mem, get_varargs_alias_set ());
 
@@ -3362,14 +3988,9 @@ mips_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
            }
        }
     }
-  if (TARGET_OLDABI)
-    {
-      /* No need for pretend arguments: the register parameter area was
-        allocated by the caller.  */
-      *pretend_size = 0;
-      return;
-    }
-  *pretend_size = (gp_saved * UNITS_PER_WORD) + (fp_saved * UNITS_PER_FPREG);
+  if (REG_PARM_STACK_SPACE (cfun->decl) == 0)
+    cfun->machine->varargs_size = (gp_saved * UNITS_PER_WORD
+                                  + fp_saved * UNITS_PER_FPREG);
 }
 
 /* Create the va_list data type.
@@ -3449,101 +4070,84 @@ mips_build_builtin_va_list (void)
 void
 mips_va_start (tree valist, rtx nextarg)
 {
-  const CUMULATIVE_ARGS *cum = &current_function_args_info;
-
-  /* ARG_POINTER_REGNUM is initialized to STACK_POINTER_BOUNDARY, but
-     since the stack is aligned for a pair of argument-passing slots,
-     and the beginning of a variable argument list may be an odd slot,
-     we have to decrease its alignment.  */
-  if (cfun && cfun->emit->regno_pointer_align)
-    while (((current_function_pretend_args_size * BITS_PER_UNIT)
-           & (REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) - 1)) != 0)
-      REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) /= 2;
-
-  if (mips_abi == ABI_EABI)
+  if (EABI_FLOAT_VARARGS_P)
     {
+      const CUMULATIVE_ARGS *cum;
+      tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff;
+      tree ovfl, gtop, ftop, goff, foff;
+      tree t;
       int gpr_save_area_size;
+      int fpr_save_area_size;
+      int fpr_offset;
 
+      cum = &current_function_args_info;
       gpr_save_area_size
        = (MAX_ARGS_IN_REGISTERS - cum->num_gprs) * UNITS_PER_WORD;
+      fpr_save_area_size
+       = (MAX_ARGS_IN_REGISTERS - cum->num_fprs) * UNITS_PER_FPREG;
 
-      if (EABI_FLOAT_VARARGS_P)
-       {
-         tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff;
-         tree ovfl, gtop, ftop, goff, foff;
-         tree t;
-         int fpr_offset;
-         int fpr_save_area_size;
-
-         f_ovfl = TYPE_FIELDS (va_list_type_node);
-         f_gtop = TREE_CHAIN (f_ovfl);
-         f_ftop = TREE_CHAIN (f_gtop);
-         f_goff = TREE_CHAIN (f_ftop);
-         f_foff = TREE_CHAIN (f_goff);
-
-         ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
-                       NULL_TREE);
-         gtop = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop,
-                       NULL_TREE);
-         ftop = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop,
-                       NULL_TREE);
-         goff = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff,
-                       NULL_TREE);
-         foff = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff,
-                       NULL_TREE);
-
-         /* Emit code to initialize OVFL, which points to the next varargs
-            stack argument.  CUM->STACK_WORDS gives the number of stack
-            words used by named arguments.  */
-         t = make_tree (TREE_TYPE (ovfl), virtual_incoming_args_rtx);
-         if (cum->stack_words > 0)
-           t = build (PLUS_EXPR, TREE_TYPE (ovfl), t,
-                      build_int_cst (NULL_TREE,
-                                     cum->stack_words * UNITS_PER_WORD));
-         t = build (MODIFY_EXPR, TREE_TYPE (ovfl), ovfl, t);
-         expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
-
-         /* Emit code to initialize GTOP, the top of the GPR save area.  */
-         t = make_tree (TREE_TYPE (gtop), virtual_incoming_args_rtx);
-         t = build (MODIFY_EXPR, TREE_TYPE (gtop), gtop, t);
-         expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
-
-         /* Emit code to initialize FTOP, the top of the FPR save area.
-            This address is gpr_save_area_bytes below GTOP, rounded
-            down to the next fp-aligned boundary.  */
-         t = make_tree (TREE_TYPE (ftop), virtual_incoming_args_rtx);
-         fpr_offset = gpr_save_area_size + UNITS_PER_FPVALUE - 1;
-         fpr_offset &= ~(UNITS_PER_FPVALUE - 1);
-         if (fpr_offset)
-           t = build (PLUS_EXPR, TREE_TYPE (ftop), t,
-                      build_int_cst (NULL_TREE, -fpr_offset));
-         t = build (MODIFY_EXPR, TREE_TYPE (ftop), ftop, t);
-         expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
-
-         /* Emit code to initialize GOFF, the offset from GTOP of the
-            next GPR argument.  */
-         t = build (MODIFY_EXPR, TREE_TYPE (goff), goff,
-                    build_int_cst (NULL_TREE, gpr_save_area_size));
-         expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
-
-         /* Likewise emit code to initialize FOFF, the offset from FTOP
-            of the next FPR argument.  */
-         fpr_save_area_size
-           = (MAX_ARGS_IN_REGISTERS - cum->num_fprs) * UNITS_PER_FPREG;
-         t = build (MODIFY_EXPR, TREE_TYPE (foff), foff,
-                    build_int_cst (NULL_TREE, fpr_save_area_size));
-         expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
-       }
-      else
-       {
-         /* Everything is in the GPR save area, or in the overflow
-            area which is contiguous with it.  */
-         nextarg = plus_constant (nextarg, -gpr_save_area_size);
-         std_expand_builtin_va_start (valist, nextarg);
-       }
+      f_ovfl = TYPE_FIELDS (va_list_type_node);
+      f_gtop = TREE_CHAIN (f_ovfl);
+      f_ftop = TREE_CHAIN (f_gtop);
+      f_goff = TREE_CHAIN (f_ftop);
+      f_foff = TREE_CHAIN (f_goff);
+
+      ovfl = build3 (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
+                    NULL_TREE);
+      gtop = build3 (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop,
+                    NULL_TREE);
+      ftop = build3 (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop,
+                    NULL_TREE);
+      goff = build3 (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff,
+                    NULL_TREE);
+      foff = build3 (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff,
+                    NULL_TREE);
+
+      /* Emit code to initialize OVFL, which points to the next varargs
+        stack argument.  CUM->STACK_WORDS gives the number of stack
+        words used by named arguments.  */
+      t = make_tree (TREE_TYPE (ovfl), virtual_incoming_args_rtx);
+      if (cum->stack_words > 0)
+       t = build2 (PLUS_EXPR, TREE_TYPE (ovfl), t,
+                   build_int_cst (NULL_TREE,
+                                  cum->stack_words * UNITS_PER_WORD));
+      t = build2 (MODIFY_EXPR, TREE_TYPE (ovfl), ovfl, t);
+      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+      /* Emit code to initialize GTOP, the top of the GPR save area.  */
+      t = make_tree (TREE_TYPE (gtop), virtual_incoming_args_rtx);
+      t = build2 (MODIFY_EXPR, TREE_TYPE (gtop), gtop, t);
+      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+      /* Emit code to initialize FTOP, the top of the FPR save area.
+        This address is gpr_save_area_bytes below GTOP, rounded
+        down to the next fp-aligned boundary.  */
+      t = make_tree (TREE_TYPE (ftop), virtual_incoming_args_rtx);
+      fpr_offset = gpr_save_area_size + UNITS_PER_FPVALUE - 1;
+      fpr_offset &= ~(UNITS_PER_FPVALUE - 1);
+      if (fpr_offset)
+       t = build2 (PLUS_EXPR, TREE_TYPE (ftop), t,
+                   build_int_cst (NULL_TREE, -fpr_offset));
+      t = build2 (MODIFY_EXPR, TREE_TYPE (ftop), ftop, t);
+      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+      /* Emit code to initialize GOFF, the offset from GTOP of the
+        next GPR argument.  */
+      t = build2 (MODIFY_EXPR, TREE_TYPE (goff), goff,
+                 build_int_cst (NULL_TREE, gpr_save_area_size));
+      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+      /* Likewise emit code to initialize FOFF, the offset from FTOP
+        of the next FPR argument.  */
+      t = build2 (MODIFY_EXPR, TREE_TYPE (foff), foff,
+                 build_int_cst (NULL_TREE, fpr_save_area_size));
+      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
     }
   else
-    std_expand_builtin_va_start (valist, nextarg);
+    {
+      nextarg = plus_constant (nextarg, -cfun->machine->varargs_size);
+      std_expand_builtin_va_start (valist, nextarg);
+    }
 }
 \f
 /* Implement va_arg.  */
@@ -3610,16 +4214,16 @@ mips_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
 
         [1] and [9] can sometimes be optimized away.  */
 
-      ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
-                   NULL_TREE);
+      ovfl = build3 (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
+                    NULL_TREE);
 
       if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT
          && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_FPVALUE)
        {
-         top = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop,
-                      NULL_TREE);
-         off = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff,
-                      NULL_TREE);
+         top = build3 (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop,
+                       NULL_TREE);
+         off = build3 (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff,
+                       NULL_TREE);
 
          /* When floating-point registers are saved to the stack,
             each one will take up UNITS_PER_HWFPVALUE bytes, regardless
@@ -3647,41 +4251,42 @@ mips_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
        }
       else
        {
-         top = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop,
-                      NULL_TREE);
-         off = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff,
-                      NULL_TREE);
+         top = build3 (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop,
+                       NULL_TREE);
+         off = build3 (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff,
+                       NULL_TREE);
          if (rsize > UNITS_PER_WORD)
            {
              /* [1] Emit code for: off &= -rsize.      */
-             t = build (BIT_AND_EXPR, TREE_TYPE (off), off,
-                        build_int_cst (NULL_TREE, -rsize));
-             t = build (MODIFY_EXPR, TREE_TYPE (off), off, t);
+             t = build2 (BIT_AND_EXPR, TREE_TYPE (off), off,
+                         build_int_cst (NULL_TREE, -rsize));
+             t = build2 (MODIFY_EXPR, TREE_TYPE (off), off, t);
              gimplify_and_add (t, pre_p);
            }
          osize = rsize;
        }
 
       /* [2] Emit code to branch if off == 0.  */
-      t = lang_hooks.truthvalue_conversion (off);
-      addr = build (COND_EXPR, ptr_type_node, t, NULL, NULL);
+      t = build2 (NE_EXPR, boolean_type_node, off,
+                 build_int_cst (TREE_TYPE (off), 0));
+      addr = build3 (COND_EXPR, ptr_type_node, t, NULL_TREE, NULL_TREE);
 
       /* [5] Emit code for: off -= rsize.  We do this as a form of
         post-increment not available to C.  Also widen for the
         coming pointer arithmetic.  */
       t = fold_convert (TREE_TYPE (off), build_int_cst (NULL_TREE, rsize));
-      t = build (POSTDECREMENT_EXPR, TREE_TYPE (off), off, t);
+      t = build2 (POSTDECREMENT_EXPR, TREE_TYPE (off), off, t);
       t = fold_convert (sizetype, t);
       t = fold_convert (TREE_TYPE (top), t);
 
       /* [4] Emit code for: addr_rtx = top - off.  On big endian machines,
         the argument has RSIZE - SIZE bytes of leading padding.  */
-      t = build (MINUS_EXPR, TREE_TYPE (top), top, t);
+      t = build2 (MINUS_EXPR, TREE_TYPE (top), top, t);
       if (BYTES_BIG_ENDIAN && rsize > size)
        {
          u = fold_convert (TREE_TYPE (t), build_int_cst (NULL_TREE,
                                                          rsize - size));
-         t = build (PLUS_EXPR, TREE_TYPE (t), t, u);
+         t = build2 (PLUS_EXPR, TREE_TYPE (t), t, u);
        }
       COND_EXPR_THEN (addr) = t;
 
@@ -3690,11 +4295,11 @@ mips_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
          /* [9] Emit: ovfl += ((intptr_t) ovfl + osize - 1) & -osize.  */
          u = fold_convert (TREE_TYPE (ovfl),
                            build_int_cst (NULL_TREE, osize - 1));
-         t = build (PLUS_EXPR, TREE_TYPE (ovfl), ovfl, u);
+         t = build2 (PLUS_EXPR, TREE_TYPE (ovfl), ovfl, u);
          u = fold_convert (TREE_TYPE (ovfl),
                            build_int_cst (NULL_TREE, -osize));
-         t = build (BIT_AND_EXPR, TREE_TYPE (ovfl), t, u);
-         align = build (MODIFY_EXPR, TREE_TYPE (ovfl), ovfl, t);
+         t = build2 (BIT_AND_EXPR, TREE_TYPE (ovfl), t, u);
+         align = build2 (MODIFY_EXPR, TREE_TYPE (ovfl), ovfl, t);
        }
       else
        align = NULL;
@@ -3704,25 +4309,25 @@ mips_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
         the argument has OSIZE - SIZE bytes of leading padding.  */
       u = fold_convert (TREE_TYPE (ovfl),
                        build_int_cst (NULL_TREE, osize));
-      t = build (POSTINCREMENT_EXPR, TREE_TYPE (ovfl), ovfl, u);
+      t = build2 (POSTINCREMENT_EXPR, TREE_TYPE (ovfl), ovfl, u);
       if (BYTES_BIG_ENDIAN && osize > size)
        {
          u = fold_convert (TREE_TYPE (t),
                            build_int_cst (NULL_TREE, osize - size));
-         t = build (PLUS_EXPR, TREE_TYPE (t), t, u);
+         t = build2 (PLUS_EXPR, TREE_TYPE (t), t, u);
        }
 
       /* String [9] and [10,11] together.  */
       if (align)
-       t = build (COMPOUND_EXPR, TREE_TYPE (t), align, t);
+       t = build2 (COMPOUND_EXPR, TREE_TYPE (t), align, t);
       COND_EXPR_ELSE (addr) = t;
 
       addr = fold_convert (build_pointer_type (type), addr);
-      addr = build_fold_indirect_ref (addr);
+      addr = build_va_arg_indirect_ref (addr);
     }
 
   if (indirect)
-    addr = build_fold_indirect_ref (addr);
+    addr = build_va_arg_indirect_ref (addr);
 
   return addr;
 }
@@ -3738,7 +4343,7 @@ mips_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
    left-side instructions (lwl, swl, ldl, sdl).
 
    *RIGHT is a QImode reference to the opposite end of the field and
-   can be used in the parterning right-side instruction.  */
+   can be used in the patterning right-side instruction.  */
 
 static bool
 mips_get_unaligned_mem (rtx *op, unsigned int width, int bitpos,
@@ -3748,7 +4353,7 @@ mips_get_unaligned_mem (rtx *op, unsigned int width, int bitpos,
 
   /* Check that the operand really is a MEM.  Not all the extv and
      extzv predicates are checked.  */
-  if (GET_CODE (*op) != MEM)
+  if (!MEM_P (*op))
     return false;
 
   /* Check that the size is valid.  */
@@ -3854,15 +4459,47 @@ mips_expand_unaligned_store (rtx dest, rtx src, unsigned int width, int bitpos)
     }
   return true;
 }
-\f
-/* Set up globals to generate code for the ISA or processor
-   described by INFO.  */
 
-static void
-mips_set_architecture (const struct mips_cpu_info *info)
-{
-  if (info != 0)
-    {
+/* Return true if (zero_extract OP SIZE POSITION) can be used as the
+   source of an "ext" instruction or the destination of an "ins"
+   instruction.  OP must be a register operand and the following
+   conditions must hold:
+
+     0 <= POSITION < GET_MODE_BITSIZE (GET_MODE (op))
+     0 < SIZE <= GET_MODE_BITSIZE (GET_MODE (op))
+     0 < POSITION + SIZE <= GET_MODE_BITSIZE (GET_MODE (op))
+
+   Also reject lengths equal to a word as they are better handled
+   by the move patterns.  */
+
+bool
+mips_use_ins_ext_p (rtx op, rtx size, rtx position)
+{
+  HOST_WIDE_INT len, pos;
+
+  if (!ISA_HAS_EXT_INS
+      || !register_operand (op, VOIDmode)
+      || GET_MODE_BITSIZE (GET_MODE (op)) > BITS_PER_WORD)
+    return false;
+
+  len = INTVAL (size);
+  pos = INTVAL (position);
+  
+  if (len <= 0 || len >= GET_MODE_BITSIZE (GET_MODE (op)) 
+      || pos < 0 || pos + len > GET_MODE_BITSIZE (GET_MODE (op)))
+    return false;
+
+  return true;
+}
+
+/* Set up globals to generate code for the ISA or processor
+   described by INFO.  */
+
+static void
+mips_set_architecture (const struct mips_cpu_info *info)
+{
+  if (info != 0)
+    {
       mips_arch_info = info;
       mips_arch = info->cpu;
       mips_isa = info->isa;
@@ -3882,6 +4519,44 @@ mips_set_tune (const struct mips_cpu_info *info)
     }
 }
 
+/* Implement TARGET_HANDLE_OPTION.  */
+
+static bool
+mips_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
+{
+  switch (code)
+    {
+    case OPT_mabi_:
+      if (strcmp (arg, "32") == 0)
+       mips_abi = ABI_32;
+      else if (strcmp (arg, "o64") == 0)
+       mips_abi = ABI_O64;
+      else if (strcmp (arg, "n32") == 0)
+       mips_abi = ABI_N32;
+      else if (strcmp (arg, "64") == 0)
+       mips_abi = ABI_64;
+      else if (strcmp (arg, "eabi") == 0)
+       mips_abi = ABI_EABI;
+      else
+       return false;
+      return true;
+
+    case OPT_march_:
+    case OPT_mtune_:
+      return mips_parse_cpu (arg) != 0;
+
+    case OPT_mips:
+      mips_isa_info = mips_parse_cpu (ACONCAT (("mips", arg, NULL)));
+      return mips_isa_info != 0;
+
+    case OPT_mno_flush_func:
+      mips_cache_flush_func = NULL;
+      return true;
+
+    default:
+      return true;
+    }
+}
 
 /* Set up the threshold for data to go into the small data area, instead
    of the normal data area, and detect any conflicts in the switches.  */
@@ -3894,57 +4569,28 @@ override_options (void)
 
   mips_section_threshold = g_switch_set ? g_switch_value : MIPS_DEFAULT_GVALUE;
 
-  /* Interpret -mabi.  */
-  mips_abi = MIPS_ABI_DEFAULT;
-  if (mips_abi_string != 0)
-    {
-      if (strcmp (mips_abi_string, "32") == 0)
-       mips_abi = ABI_32;
-      else if (strcmp (mips_abi_string, "o64") == 0)
-       mips_abi = ABI_O64;
-      else if (strcmp (mips_abi_string, "n32") == 0)
-       mips_abi = ABI_N32;
-      else if (strcmp (mips_abi_string, "64") == 0)
-       mips_abi = ABI_64;
-      else if (strcmp (mips_abi_string, "eabi") == 0)
-       mips_abi = ABI_EABI;
-      else
-       fatal_error ("bad value (%s) for -mabi= switch", mips_abi_string);
-    }
-
   /* The following code determines the architecture and register size.
      Similar code was added to GAS 2.14 (see tc-mips.c:md_after_parse_args()).
      The GAS and GCC code should be kept in sync as much as possible.  */
 
   if (mips_arch_string != 0)
-    mips_set_architecture (mips_parse_cpu ("-march", mips_arch_string));
+    mips_set_architecture (mips_parse_cpu (mips_arch_string));
 
-  if (mips_isa_string != 0)
+  if (mips_isa_info != 0)
     {
-      /* Handle -mipsN.  */
-      char *whole_isa_str = concat ("mips", mips_isa_string, NULL);
-      const struct mips_cpu_info *isa_info;
-
-      isa_info = mips_parse_cpu ("-mips option", whole_isa_str);
-      free (whole_isa_str);
-
-      /* -march takes precedence over -mipsN, since it is more descriptive.
-        There's no harm in specifying both as long as the ISA levels
-        are the same.  */
-      if (mips_arch_info != 0 && mips_isa != isa_info->isa)
-       error ("-mips%s conflicts with the other architecture options, "
-              "which specify a MIPS%d processor",
-              mips_isa_string, mips_isa);
-
-      /* Set architecture based on the given option.  */
-      mips_set_architecture (isa_info);
+      if (mips_arch_info == 0)
+       mips_set_architecture (mips_isa_info);
+      else if (mips_arch_info->isa != mips_isa_info->isa)
+       error ("-%s conflicts with the other architecture options, "
+              "which specify a %s processor",
+              mips_isa_info->name,
+              mips_cpu_info_from_isa (mips_arch_info->isa)->name);
     }
 
   if (mips_arch_info == 0)
     {
 #ifdef MIPS_CPU_STRING_DEFAULT
-      mips_set_architecture (mips_parse_cpu ("default CPU",
-                                            MIPS_CPU_STRING_DEFAULT));
+      mips_set_architecture (mips_parse_cpu (MIPS_CPU_STRING_DEFAULT));
 #else
       mips_set_architecture (mips_cpu_info_from_isa (MIPS_ISA_DEFAULT));
 #endif
@@ -3956,11 +4602,14 @@ override_options (void)
 
   /* Optimize for mips_arch, unless -mtune selects a different processor.  */
   if (mips_tune_string != 0)
-    mips_set_tune (mips_parse_cpu ("-mtune", mips_tune_string));
+    mips_set_tune (mips_parse_cpu (mips_tune_string));
 
   if (mips_tune_info == 0)
     mips_set_tune (mips_arch_info);
 
+  /* Set cost structure for the processor.  */
+  mips_cost = &mips_rtx_cost_data[mips_tune];
+
   if ((target_flags_explicit & MASK_64BIT) != 0)
     {
       /* The user specified the size of the integer registers.  Make sure
@@ -4008,10 +4657,6 @@ override_options (void)
 
   if ((target_flags_explicit & MASK_LONG64) == 0)
     {
-      /* If no type size setting options (-mlong64,-mint64,-mlong32)
-        were used, then set the type sizes.  In the EABI in 64 bit mode,
-        longs and pointers are 64 bits.  Likewise for the SGI Irix6 N64
-        ABI.  */
       if ((mips_abi == ABI_EABI && TARGET_64BIT) || mips_abi == ABI_64)
        target_flags |= MASK_LONG64;
       else
@@ -4067,7 +4712,7 @@ override_options (void)
        target_flags &= ~MASK_BRANCHLIKELY;
     }
   if (TARGET_BRANCHLIKELY && !ISA_HAS_BRANCHLIKELY)
-    warning ("generation of Branch Likely instructions enabled, but not supported by architecture");
+    warning (0, "generation of Branch Likely instructions enabled, but not supported by architecture");
 
   /* The effect of -mabicalls isn't defined for the EABI.  */
   if (mips_abi == ABI_EABI && TARGET_ABICALLS)
@@ -4084,7 +4729,7 @@ override_options (void)
     {
       flag_pic = 1;
       if (mips_section_threshold > 0)
-       warning ("-G is incompatible with PIC code which is the default");
+       warning (0, "-G is incompatible with PIC code which is the default");
     }
 
   /* mips_split_addresses is a half-way house between explicit
@@ -4124,6 +4769,10 @@ override_options (void)
          increase register pressure.  */
       flag_schedule_insns = 0;
 
+      /* Don't do hot/cold partitioning.  The constant layout code expects
+        the whole function to be in a single section.  */
+      flag_reorder_blocks_and_partition = 0;
+
       /* Silently disable -mexplicit-relocs since it doesn't apply
         to mips16 code.  Even so, it would overly pedantic to warn
         about "-mips16 -mexplicit-relocs", especially given that
@@ -4145,13 +4794,13 @@ override_options (void)
 
   /* Make sure that the user didn't turn off paired single support when
      MIPS-3D support is requested.  */
-  if (TARGET_MIPS3D && (target_flags_explicit & MASK_PAIRED_SINGLE)
+  if (TARGET_MIPS3D && (target_flags_explicit & MASK_PAIRED_SINGLE_FLOAT)
       && !TARGET_PAIRED_SINGLE_FLOAT)
     error ("-mips3d requires -mpaired-single");
 
-  /* If TARGET_MIPS3D, enable MASK_PAIRED_SINGLE.  */
+  /* If TARGET_MIPS3D, enable MASK_PAIRED_SINGLE_FLOAT.  */
   if (TARGET_MIPS3D)
-    target_flags |= MASK_PAIRED_SINGLE;
+    target_flags |= MASK_PAIRED_SINGLE_FLOAT;
 
   /* Make sure that when TARGET_PAIRED_SINGLE_FLOAT is true, TARGET_FLOAT64
      and TARGET_HARD_FLOAT are both true.  */
@@ -4163,6 +4812,9 @@ override_options (void)
   if (TARGET_PAIRED_SINGLE_FLOAT && !ISA_MIPS64)
     error ("-mips3d/-mpaired-single must be used with -mips64");
 
+  if (TARGET_MIPS16 && TARGET_DSP)
+    error ("-mips16 and -mdsp cannot be used together");
+
   mips_print_operand_punct['?'] = 1;
   mips_print_operand_punct['#'] = 1;
   mips_print_operand_punct['/'] = 1;
@@ -4196,11 +4848,14 @@ override_options (void)
                             GR_REGS);
   mips_char_to_class['e'] = LEA_REGS;
   mips_char_to_class['j'] = PIC_FN_ADDR_REG;
+  mips_char_to_class['v'] = V1_REG;
   mips_char_to_class['y'] = GR_REGS;
   mips_char_to_class['z'] = ST_REGS;
   mips_char_to_class['B'] = COP0_REGS;
   mips_char_to_class['C'] = COP2_REGS;
   mips_char_to_class['D'] = COP3_REGS;
+  mips_char_to_class['A'] = DSP_ACC_REGS;
+  mips_char_to_class['a'] = ACC_REGS;
 
   /* Set up array to map GCC register number to debug register number.
      Ignore the special purpose register numbers.  */
@@ -4266,10 +4921,10 @@ override_options (void)
                        /* Allow TFmode for CCmode reloads.  */
                        || (ISA_HAS_8CC && mode == TFmode));
 
-         else if (MD_REG_P (regno))
+          else if (ACC_REG_P (regno))
            temp = (INTEGRAL_MODE_P (mode)
                    && (size <= UNITS_PER_WORD
-                       || (regno == MD_REG_FIRST
+                       || (ACC_HI_REG_P (regno)
                            && size == 2 * UNITS_PER_WORD)));
 
          else if (ALL_COP_REG_P (regno))
@@ -4384,6 +5039,22 @@ override_options (void)
       mips_lo_relocs[SYMBOL_GOTOFF_LOADGP] = "%lo(%neg(%gp_rel(";
     }
 
+  /* Thread-local relocation operators.  */
+  mips_lo_relocs[SYMBOL_TLSGD] = "%tlsgd(";
+  mips_lo_relocs[SYMBOL_TLSLDM] = "%tlsldm(";
+  mips_split_p[SYMBOL_DTPREL] = 1;
+  mips_hi_relocs[SYMBOL_DTPREL] = "%dtprel_hi(";
+  mips_lo_relocs[SYMBOL_DTPREL] = "%dtprel_lo(";
+  mips_lo_relocs[SYMBOL_GOTTPREL] = "%gottprel(";
+  mips_split_p[SYMBOL_TPREL] = 1;
+  mips_hi_relocs[SYMBOL_TPREL] = "%tprel_hi(";
+  mips_lo_relocs[SYMBOL_TPREL] = "%tprel_lo(";
+
+  /* We don't have a thread pointer access instruction on MIPS16, or
+     appropriate TLS relocations.  */
+  if (TARGET_MIPS16)
+    targetm.have_tls = false;
+
   /* Default to working around R4000 errata only if the processor
      was selected explicitly.  */
   if ((target_flags_explicit & MASK_FIX_R4000) == 0
@@ -4402,6 +5073,13 @@ override_options (void)
 void
 mips_conditional_register_usage (void)
 {
+  if (!TARGET_DSP)
+    {
+      int regno;
+
+      for (regno = DSP_ACC_REG_FIRST; regno <= DSP_ACC_REG_LAST; regno++)
+       fixed_regs[regno] = call_used_regs[regno] = 1;
+    }
   if (!TARGET_HARD_FLOAT)
     {
       int regno;
@@ -4526,31 +5204,6 @@ mips_debugger_offset (rtx addr, HOST_WIDE_INT offset)
   return offset;
 }
 \f
-/* A helper function for print_operand.  This prints out a floating point
-   condition code register.  OP is the operand we are printing.  CODE is the
-   rtx code of OP.  ALIGN is the required register alignment for OP.  OFFSET
-   is the index into operand for multiple register operands.  If IGNORE is
-   true, then we only print the register name if it isn't fcc0, and we
-   follow it with a comma.  */
-
-static void
-print_fcc_operand (FILE *file, rtx op, enum rtx_code code,
-                  int align, int offset, int ignore)
-{
-  int regnum;
-
-  if (code != REG)
-    abort ();
-
-  regnum = REGNO (op);
-  if (!ST_REG_P (regnum)
-      || (regnum - ST_REG_FIRST) % align != 0)
-    abort ();
-
-  if (!ignore || regnum != ST_REG_FIRST)
-    fprintf (file, "%s%s", reg_names[regnum+offset], (ignore ? "," : ""));
-}
-
 /* Implement the PRINT_OPERAND macro.  The MIPS-specific operand codes are:
 
    'X'  OP is CONST_INT, prints 32 bits in hexadecimal format = "0x%08x",
@@ -4568,16 +5221,10 @@ print_fcc_operand (FILE *file, rtx op, enum rtx_code code,
    'T'  print 'f' for (eq:CC ...), 't' for (ne:CC ...),
              'z' for (eq:?I ...), 'n' for (ne:?I ...).
    't'  like 'T', but with the EQ/NE cases reversed
-   'Z'  print register and a comma, but print nothing for $fcc0
+   'Y'  for a CONST_INT X, print mips_fp_conditions[X]
+   'Z'  print the operand and a comma for ISA_HAS_8CC, otherwise print nothing
    'R'  print the reloc associated with LO_SUM
-   'Y'  Check if the fcc register number is even.  Then print the fcc register 
-        plus 1.
-   'y'  Check if the fcc register number is even.  Then print the fcc register.
-   'V'  Check if the fcc register number divided by 4 is zero.  Then print 
-        the fcc register plus 2.
-   'v'  Check if the fcc register number divided by 4 is zero.  Then print 
-        the fcc register.
-   'Q'  print the fcc register.
+   'q'  print DSP accumulator registers
 
    The punctuation characters are:
 
@@ -4809,23 +5456,40 @@ print_operand (FILE *file, rtx op, int letter)
   else if (letter == 'R')
     print_operand_reloc (file, op, mips_lo_relocs);
 
-  else if (letter == 'Z')
-    print_fcc_operand (file, op, code, 1, 0, 1);
-
   else if (letter == 'Y')
-    print_fcc_operand (file, op, code, 2, 1, 0);
+    {
+      if (GET_CODE (op) == CONST_INT
+         && ((unsigned HOST_WIDE_INT) INTVAL (op)
+             < ARRAY_SIZE (mips_fp_conditions)))
+       fputs (mips_fp_conditions[INTVAL (op)], file);
+      else
+       output_operand_lossage ("invalid %%Y value");
+    }
 
-  else if (letter == 'y')
-    print_fcc_operand (file, op, code, 2, 0, 0);
+  else if (letter == 'Z')
+    {
+      if (ISA_HAS_8CC)
+       {
+         print_operand (file, op, 0);
+         fputc (',', file);
+       }
+    }
 
-  else if (letter == 'V')
-    print_fcc_operand (file, op, code, 4, 2, 0);
+  else if (letter == 'q')
+    {
+      int regnum;
 
-  else if (letter == 'v')
-    print_fcc_operand (file, op, code, 4, 0, 0);
+      if (code != REG)
+       fatal_insn ("PRINT_OPERAND, invalid insn for %%q", op);
 
-  else if (letter == 'Q')
-    print_fcc_operand (file, op, code, 1, 0, 0);
+      regnum = REGNO (op);
+      if (MD_REG_P (regnum))
+       fprintf (file, "$ac0");
+      else if (DSP_ACC_REG_P (regnum))
+       fprintf (file, "$ac%c", reg_names[regnum][3]);
+      else
+       fatal_insn ("PRINT_OPERAND, invalid insn for %%q", op);
+    }
 
   else if (code == REG || code == SUBREG)
     {
@@ -4936,7 +5600,7 @@ print_operand_address (FILE *file, rtx x)
        output_addr_const (file, x);
        return;
       }
-  abort ();
+  gcc_unreachable ();
 }
 \f
 /* When using assembler macros, keep track of all of small-data externs
@@ -4996,7 +5660,6 @@ irix_output_external_libcall (rtx fun)
 void
 mips_output_filename (FILE *stream, const char *name)
 {
-  char ltext_label_name[100];
 
   /* If we are emitting DWARF-2, let dwarf2out handle the ".file"
      directives.  */
@@ -5007,44 +5670,24 @@ mips_output_filename (FILE *stream, const char *name)
       mips_output_filename_first_time = 0;
       num_source_filenames += 1;
       current_function_file = name;
-      ASM_OUTPUT_FILENAME (stream, num_source_filenames, name);
+      fprintf (stream, "\t.file\t%d ", num_source_filenames);
+      output_quoted_string (stream, name);
+      putc ('\n', stream);
     }
 
+  /* If we are emitting stabs, let dbxout.c handle this (except for
+     the mips_output_filename_first_time case).  */
   else if (write_symbols == DBX_DEBUG)
-    {
-      ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
-      fputs ("\t.stabs\t", stream);
-      output_quoted_string (stream, name);
-      fprintf (stream, ",%d,0,0,%s\n", N_SOL, &ltext_label_name[1]);
-    }
+    return;
 
   else if (name != current_function_file
           && strcmp (name, current_function_file) != 0)
     {
       num_source_filenames += 1;
       current_function_file = name;
-      ASM_OUTPUT_FILENAME (stream, num_source_filenames, name);
-    }
-}
-\f
-/* Emit a linenumber.  For encapsulated stabs, we need to put out a stab
-   as well as a .loc, since it is possible that MIPS ECOFF might not be
-   able to represent the location for inlines that come from a different
-   file.  */
-
-void
-mips_output_lineno (FILE *stream, int line)
-{
-  if (write_symbols == DBX_DEBUG)
-    {
-      ++sym_lineno;
-      fprintf (stream, "%sLM%d:\n\t.stabn\t%d,0,%d,%sLM%d\n",
-              LOCAL_LABEL_PREFIX, sym_lineno, N_SLINE, line,
-              LOCAL_LABEL_PREFIX, sym_lineno);
-    }
-  else
-    {
-      fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
+      fprintf (stream, "\t.file\t%d ", num_source_filenames);
+      output_quoted_string (stream, name);
+      putc ('\n', stream);
     }
 }
 \f
@@ -5066,56 +5709,20 @@ mips_output_ascii (FILE *stream, const char *string_param, size_t len,
     {
       register int c = string[i];
 
-      switch (c)
+      if (ISPRINT (c))
        {
-       case '\"':
-       case '\\':
-         putc ('\\', stream);
-         putc (c, stream);
-         cur_pos += 2;
-         break;
-
-       case TARGET_NEWLINE:
-         fputs ("\\n", stream);
-         if (i+1 < len
-             && (((c = string[i+1]) >= '\040' && c <= '~')
-                 || c == TARGET_TAB))
-           cur_pos = 32767;            /* break right here */
-         else
-           cur_pos += 2;
-         break;
-
-       case TARGET_TAB:
-         fputs ("\\t", stream);
-         cur_pos += 2;
-         break;
-
-       case TARGET_FF:
-         fputs ("\\f", stream);
-         cur_pos += 2;
-         break;
-
-       case TARGET_BS:
-         fputs ("\\b", stream);
-         cur_pos += 2;
-         break;
-
-       case TARGET_CR:
-         fputs ("\\r", stream);
-         cur_pos += 2;
-         break;
-
-       default:
-         if (c >= ' ' && c < 0177)
+         if (c == '\\' || c == '\"')
            {
-             putc (c, stream);
+             putc ('\\', stream);
              cur_pos++;
            }
-         else
-           {
-             fprintf (stream, "\\%03o", c);
-             cur_pos += 4;
-           }
+         putc (c, stream);
+         cur_pos++;
+       }
+      else
+       {
+         fprintf (stream, "\\%03o", c);
+         cur_pos += 4;
        }
 
       if (cur_pos > 72 && i+1 < len)
@@ -5153,7 +5760,7 @@ mips_file_start (void)
        case ABI_O64:  abi_string = "abiO64"; break;
        case ABI_EABI: abi_string = TARGET_64BIT ? "eabi64" : "eabi32"; break;
        default:
-         abort ();
+         gcc_unreachable ();
        }
       /* Note - we use fprintf directly rather than called named_section()
         because in this way we can avoid creating an allocated section.  We
@@ -5353,7 +5960,7 @@ mips_declare_object_name (FILE *stream, const char *name,
       ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
     }
 
-  mips_declare_object (stream, name, "", ":\n", 0);
+  mips_declare_object (stream, name, "", ":\n");
 }
 
 /* Implement ASM_FINISH_DECLARE_OBJECT.  This is generic ELF stuff.  */
@@ -5577,7 +6184,7 @@ mips_save_reg_p (unsigned int regno)
 /* Return the bytes needed to compute the frame pointer from the current
    stack pointer.  SIZE is the size (in bytes) of the local variables.
 
-   Mips stack frames look like:
+   MIPS stack frames look like:
 
              Before call                       After call
         +-----------------------+      +-----------------------+
@@ -5705,10 +6312,9 @@ compute_frame_size (HOST_WIDE_INT size)
   gp_reg_rounded = MIPS_STACK_ALIGN (gp_reg_size);
   total_size += gp_reg_rounded + MIPS_STACK_ALIGN (fp_reg_size);
 
-  /* Add in space reserved on the stack by the callee for storing arguments
-     passed in registers.  */
-  if (!TARGET_OLDABI)
-    total_size += MIPS_STACK_ALIGN (current_function_pretend_args_size);
+  /* Add in the space required for saving incoming register arguments.  */
+  total_size += current_function_pretend_args_size;
+  total_size += MIPS_STACK_ALIGN (cfun->machine->varargs_size);
 
   /* Save other computed information.  */
   cfun->machine->frame.total_size = total_size;
@@ -5777,13 +6383,12 @@ mips_initial_elimination_offset (int from, int to)
       break;
 
     case ARG_POINTER_REGNUM:
-      offset = cfun->machine->frame.total_size;
-      if (TARGET_NEWABI)
-       offset -= current_function_pretend_args_size;
+      offset = (cfun->machine->frame.total_size
+               - current_function_pretend_args_size);
       break;
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
   if (TARGET_MIPS16 && to == HARD_FRAME_POINTER_REGNUM)
@@ -5901,7 +6506,7 @@ mips_output_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
 
 #ifdef SDB_DEBUGGING_INFO
   if (debug_info_level != DINFO_LEVEL_TERSE && write_symbols == SDB_DEBUG)
-    ASM_OUTPUT_SOURCE_LINE (file, DECL_SOURCE_LINE (current_function_decl), 0);
+    SDB_OUTPUT_SOURCE_LINE (file, DECL_SOURCE_LINE (current_function_decl));
 #endif
 
   /* In mips16 mode, we may need to generate a 32 bit to handle
@@ -6006,8 +6611,18 @@ mips_set_frame_expr (rtx frame_pattern)
 static rtx
 mips_frame_set (rtx mem, rtx reg)
 {
-  rtx set = gen_rtx_SET (VOIDmode, mem, reg);
+  rtx set;
+
+  /* If we're saving the return address register and the dwarf return
+     address column differs from the hard register number, adjust the
+     note reg to refer to the former.  */
+  if (REGNO (reg) == GP_REG_FIRST + 31
+      && DWARF_FRAME_RETURN_COLUMN != GP_REG_FIRST + 31)
+    reg = gen_rtx_REG (GET_MODE (reg), DWARF_FRAME_RETURN_COLUMN);
+
+  set = gen_rtx_SET (VOIDmode, mem, reg);
   RTX_FRAME_RELATED_P (set) = 1;
+
   return set;
 }
 
@@ -6093,9 +6708,7 @@ mips_expand_prologue (void)
                 from the stack pointer, so use the frame pointer as a
                 temporary.  We should always be using a frame pointer
                 in this case anyway.  */
-             if (!frame_pointer_needed)
-               abort ();
-
+             gcc_assert (frame_pointer_needed);
              emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
              emit_insn (gen_sub3_insn (hard_frame_pointer_rtx,
                                        hard_frame_pointer_rtx,
@@ -6123,10 +6736,23 @@ mips_expand_prologue (void)
       if (TARGET_MIPS16 && cfun->machine->frame.args_size != 0)
        {
          rtx offset = GEN_INT (cfun->machine->frame.args_size);
-         RTX_FRAME_RELATED_P
-           (emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
-                                      stack_pointer_rtx,
-                                      offset))) = 1;
+         if (SMALL_OPERAND (cfun->machine->frame.args_size))
+           RTX_FRAME_RELATED_P 
+             (emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
+                                        stack_pointer_rtx,
+                                        offset))) = 1;
+         else
+           {
+             emit_move_insn (MIPS_PROLOGUE_TEMP (Pmode), offset);
+             emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
+             emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
+                                       hard_frame_pointer_rtx,
+                                       MIPS_PROLOGUE_TEMP (Pmode)));
+             mips_set_frame_expr
+               (gen_rtx_SET (VOIDmode, hard_frame_pointer_rtx,
+                             plus_constant (stack_pointer_rtx, 
+                                            cfun->machine->frame.args_size)));
+           }
        }
       else
        RTX_FRAME_RELATED_P (emit_move_insn (hard_frame_pointer_rtx,
@@ -6451,7 +7077,7 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
     mips16_lay_out_constants ();
   shorten_branches (insn);
   final_start_function (insn, file, 1);
-  final (insn, file, 1, 0);
+  final (insn, file, 1);
   final_end_function ();
 
   /* Clean up the vars set above.  Note that final_end_function resets
@@ -6517,6 +7143,42 @@ mips_select_rtx_section (enum machine_mode mode, rtx x,
     }
 }
 
+/* Implement TARGET_ASM_FUNCTION_RODATA_SECTION.
+
+   The complication here is that, with the combination TARGET_ABICALLS
+   && !TARGET_GPWORD, jump tables will use absolute addresses, and should
+   therefore not be included in the read-only part of a DSO.  Handle such
+   cases by selecting a normal data section instead of a read-only one.
+   The logic apes that in default_function_rodata_section.  */
+
+static void
+mips_function_rodata_section (tree decl)
+{
+  if (!TARGET_ABICALLS || TARGET_GPWORD)
+    default_function_rodata_section (decl);
+  else if (decl && DECL_SECTION_NAME (decl))
+    {
+      const char *name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
+      if (DECL_ONE_ONLY (decl) && strncmp (name, ".gnu.linkonce.t.", 16) == 0)
+       {
+         char *rname = ASTRDUP (name);
+         rname[14] = 'd';
+         named_section_real (rname, SECTION_LINKONCE | SECTION_WRITE, decl);
+       }
+      else if (flag_function_sections && flag_data_sections
+              && strncmp (name, ".text.", 6) == 0)
+       {
+         char *rname = ASTRDUP (name);
+         memcpy (rname + 1, "data", 4);
+         named_section_flags (rname, SECTION_WRITE);
+       }
+      else
+       data_section ();
+    }
+  else
+    data_section ();
+}
+
 /* Implement TARGET_IN_SMALL_DATA_P.  Return true if it would be safe to
    access DECL using %gp_rel(...)($gp).  */
 
@@ -6699,6 +7361,13 @@ mips_function_value (tree valtype, tree func ATTRIBUTE_UNUSED,
              mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
            }
        }
+
+      /* For EABI, the class of return register depends entirely on MODE.
+        For example, "struct { some_type x; }" and "union { some_type x; }"
+        are returned in the same way as a bare "some_type" would be.
+        Other ABIs only use FPRs for scalar, complex or vector types.  */
+      if (mips_abi != ABI_EABI && !FLOAT_TYPE_P (valtype))
+       return gen_rtx_REG (mode, GP_RETURN);
     }
 
   if ((GET_MODE_CLASS (mode) == MODE_FLOAT
@@ -6747,35 +7416,54 @@ mips_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
     }
 }
 
-/* Return the class of registers for which a mode change from FROM to TO
-   is invalid.
-
-   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.
-
-   Similarly, when using paired floating-point registers, the first
-   register holds the low word, regardless of endianness.  So in big
-   endian mode, (subreg:SI (reg:DF $f0) 0) does not get the high word
-   as intended.
+static bool
+mips_callee_copies (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
+                   enum machine_mode mode ATTRIBUTE_UNUSED,
+                   tree type ATTRIBUTE_UNUSED, bool named)
+{
+  return mips_abi == ABI_EABI && named;
+}
 
-   Also, loading a 32-bit value into a 64-bit floating-point register
-   will not sign-extend the value, despite what LOAD_EXTEND_OP says.
-   We can't allow 64-bit float registers to change from a 32-bit
-   mode to a 64-bit mode.  */
+/* Return true if registers of class CLASS cannot change from mode FROM
+   to mode TO.  */
 
 bool
 mips_cannot_change_mode_class (enum machine_mode from,
                               enum machine_mode to, enum reg_class class)
 {
-  if (GET_MODE_SIZE (from) != GET_MODE_SIZE (to))
+  if (MIN (GET_MODE_SIZE (from), GET_MODE_SIZE (to)) <= UNITS_PER_WORD
+      && MAX (GET_MODE_SIZE (from), GET_MODE_SIZE (to)) > UNITS_PER_WORD)
     {
       if (TARGET_BIG_ENDIAN)
-       return reg_classes_intersect_p (FP_REGS, class);
-      if (TARGET_FLOAT64)
-       return reg_classes_intersect_p (HI_AND_FP_REGS, class);
-      return reg_classes_intersect_p (HI_REG, class);
+       {
+         /* When a multi-word value is stored in paired floating-point
+            registers, the first register always holds the low word.
+            We therefore can't allow FPRs to change between single-word
+            and multi-word modes.  */
+         if (FP_INC > 1 && reg_classes_intersect_p (FP_REGS, class))
+           return true;
+       }
+      else
+       {
+         /* LO_REGNO == HI_REGNO + 1, so if a multi-word value is stored
+            in LO and HI, the high word always comes first.  We therefore
+            can't allow values stored in HI to change between single-word
+            and multi-word modes.
+            This rule applies to both the original HI/LO pair and the new
+            DSP accumulators.  */
+         if (reg_classes_intersect_p (ACC_REGS, class))
+           return true;
+       }
     }
+  /* Loading a 32-bit value into a 64-bit floating-point register
+     will not sign-extend the value, despite what LOAD_EXTEND_OP says.
+     We can't allow 64-bit float registers to change from SImode to
+     to a wider mode.  */
+  if (TARGET_FLOAT64
+      && from == SImode
+      && GET_MODE_SIZE (to) >= UNITS_PER_WORD
+      && reg_classes_intersect_p (FP_REGS, class))
+    return true;
   return false;
 }
 
@@ -6831,7 +7519,7 @@ mips_secondary_reload_class (enum reg_class class,
   int regno = -1;
   int gp_reg_p;
 
-  if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
+  if (REG_P (x)|| GET_CODE (x) == SUBREG)
     regno = true_regnum (x);
 
   gp_reg_p = TARGET_MIPS16 ? M16_REG_P (regno) : GP_REG_P (regno);
@@ -6844,8 +7532,10 @@ mips_secondary_reload_class (enum reg_class class,
     }
 
   /* Copying from HI or LO to anywhere other than a general register
-     requires a general register.  */
-  if (class == HI_REG || class == LO_REG || class == MD_REGS)
+     requires a general register.
+     This rule applies to both the original HI/LO pair and the new
+     DSP accumulators.  */
+  if (reg_class_subset_p (class, ACC_REGS))
     {
       if (TARGET_MIPS16 && in_p)
        {
@@ -6854,7 +7544,7 @@ mips_secondary_reload_class (enum reg_class class,
        }
       return gp_reg_p ? NO_REGS : gr_regs;
     }
-  if (MD_REG_P (regno))
+  if (ACC_REG_P (regno))
     {
       if (TARGET_MIPS16 && ! in_p)
        {
@@ -6883,7 +7573,7 @@ mips_secondary_reload_class (enum reg_class class,
 
   if (class == FP_REGS)
     {
-      if (GET_CODE (x) == MEM)
+      if (MEM_P (x))
        {
          /* In this case we can use lwc1, swc1, ldc1 or sdc1.  */
          return NO_REGS;
@@ -6954,20 +7644,29 @@ mips_class_max_nregs (enum reg_class class ATTRIBUTE_UNUSED,
     return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
 }
 
-bool
+static bool
 mips_valid_pointer_mode (enum machine_mode mode)
 {
   return (mode == SImode || (TARGET_64BIT && mode == DImode));
 }
 
 /* Target hook for vector_mode_supported_p.  */
+
 static bool
 mips_vector_mode_supported_p (enum machine_mode mode)
 {
-  if (mode == V2SFmode && TARGET_PAIRED_SINGLE_FLOAT)
-    return true;
-  else
-    return false;
+  switch (mode)
+    {
+    case V2SFmode:
+      return TARGET_PAIRED_SINGLE_FLOAT;
+
+    case V2HImode:
+    case V4QImode:
+      return TARGET_DSP;
+
+    default:
+      return false;
+    }
 }
 \f
 /* If we can access small data directly (using gp-relative relocation
@@ -7000,7 +7699,7 @@ mips16_gp_pseudo_reg (void)
       /* We need to emit the initialization after the FUNCTION_BEG
          note, so that it will be integrated.  */
       for (scan = get_insns (); scan != NULL_RTX; scan = NEXT_INSN (scan))
-       if (GET_CODE (scan) == NOTE
+       if (NOTE_P (scan)
            && NOTE_LINE_NUMBER (scan) == NOTE_INSN_FUNCTION_BEG)
          break;
       if (scan == NULL_RTX)
@@ -7026,8 +7725,7 @@ mips16_fp_args (FILE *file, int fp_code, int from_fp_p)
   unsigned int f;
 
   /* This code only works for the original 32 bit ABI and the O64 ABI.  */
-  if (!TARGET_OLDABI)
-    abort ();
+  gcc_assert (TARGET_OLDABI);
 
   if (from_fp_p)
     s = "mfc1";
@@ -7066,7 +7764,7 @@ mips16_fp_args (FILE *file, int fp_code, int from_fp_p)
            }
        }
       else
-       abort ();
+       gcc_unreachable ();
 
       ++gparg;
       ++fparg;
@@ -7223,13 +7921,12 @@ build_mips16_call_stub (rtx retval, rtx fn, rtx arg_size, int fp_code)
 
   /* This code will only work for o32 and o64 abis.  The other ABI's
      require more sophisticated support.  */
-  if (!TARGET_OLDABI)
-    abort ();
+  gcc_assert (TARGET_OLDABI);
 
   /* We can only handle SFmode and DFmode floating point return
      values.  */
-  if (fpret && GET_MODE (retval) != SFmode && GET_MODE (retval) != DFmode)
-    abort ();
+  if (fpret)
+    gcc_assert (GET_MODE (retval) == SFmode || GET_MODE (retval) == DFmode);
 
   /* If we're calling via a function pointer, then we must always call
      via a stub.  There are magic stubs provided in libgcc.a for each
@@ -7262,8 +7959,6 @@ build_mips16_call_stub (rtx retval, rtx fn, rtx arg_size, int fp_code)
       insn = emit_call_insn (insn);
 
       /* Put the register usage information on the CALL.  */
-      if (GET_CODE (insn) != CALL_INSN)
-       abort ();
       CALL_INSN_FUNCTION_USAGE (insn) =
        gen_rtx_EXPR_LIST (VOIDmode,
                           gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 2)),
@@ -7446,7 +8141,7 @@ build_mips16_call_stub (rtx retval, rtx fn, rtx arg_size, int fp_code)
      Fortunately, this case is illegal, since it means that a function
      was declared in two different ways in a single compilation.  */
   if (fpret && ! l->fpret)
-    error ("cannot handle inconsistent calls to `%s'", fnname);
+    error ("cannot handle inconsistent calls to %qs", fnname);
 
   /* If we are calling a stub which handles a floating point return
      value, we need to arrange to save $18 in the prologue.  We do
@@ -7464,9 +8159,6 @@ build_mips16_call_stub (rtx retval, rtx fn, rtx arg_size, int fp_code)
        insn = gen_call_value_internal (retval, fn, arg_size);
       insn = emit_call_insn (insn);
 
-      if (GET_CODE (insn) != CALL_INSN)
-       abort ();
-
       CALL_INSN_FUNCTION_USAGE (insn) =
        gen_rtx_EXPR_LIST (VOIDmode,
                           gen_rtx_USE (VOIDmode, gen_rtx_REG (word_mode, 18)),
@@ -7586,7 +8278,7 @@ dump_constants_1 (enum machine_mode mode, rtx value, rtx insn)
       }
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 }
 
@@ -7620,16 +8312,12 @@ dump_constants (struct mips16_constant *constants, rtx insn)
   emit_barrier_after (insn);
 }
 
-/* Return the length of instruction INSN.
-
-   ??? MIPS16 switch tables go in .text, but we don't define
-   JUMP_TABLES_IN_TEXT_SECTION, so get_attr_length will not
-   compute their lengths correctly.  */
+/* Return the length of instruction INSN.  */
 
 static int
 mips16_insn_length (rtx insn)
 {
-  if (GET_CODE (insn) == JUMP_INSN)
+  if (JUMP_P (insn))
     {
       rtx body = PATTERN (insn);
       if (GET_CODE (body) == ADDR_VEC)
@@ -7943,8 +8631,8 @@ vr4130_avoid_branch_rt_conflict (rtx insn)
 
   first = SEQ_BEGIN (insn);
   second = SEQ_END (insn);
-  if (GET_CODE (first) == JUMP_INSN
-      && GET_CODE (second) == INSN
+  if (JUMP_P (first)
+      && NONJUMP_INSN_P (second)
       && GET_CODE (PATTERN (first)) == SET
       && GET_CODE (SET_DEST (PATTERN (first))) == PC
       && GET_CODE (SET_SRC (PATTERN (first))) == IF_THEN_ELSE)
@@ -8019,7 +8707,7 @@ vr4130_align_insns (void)
               way, if the nop makes Y aligned, it will also align any labels
               between X and Y.  */
            if (state.insns_left != state.issue_rate
-               && GET_CODE (subinsn) != CALL_INSN)
+               && !CALL_P (subinsn))
              {
                if (subinsn == SEQ_BEGIN (insn) && aligned_p)
                  {
@@ -8058,7 +8746,7 @@ vr4130_align_insns (void)
             mips.md patern, the length is only an estimate.  Insert an
             8 byte alignment after it so that the following instructions
             can be handled correctly.  */
-         if (GET_CODE (SEQ_BEGIN (insn)) == INSN
+         if (NONJUMP_INSN_P (SEQ_BEGIN (insn))
              && (recog_memoized (insn) < 0 || length >= 8))
            {
              next = emit_insn_after (gen_align (GEN_INT (3)), insn);
@@ -8149,8 +8837,7 @@ mips_avoid_hazard (rtx after, rtx insn, int *hilo_delay,
 
       case HAZARD_DELAY:
        set = single_set (insn);
-       if (set == 0)
-         abort ();
+       gcc_assert (set != 0);
        *delayed_reg = SET_DEST (set);
        break;
       }
@@ -8174,10 +8861,24 @@ mips_avoid_hazards (void)
   cfun->machine->ignore_hazard_length_p = true;
   shorten_branches (get_insns ());
 
-  /* The profiler code uses assembler macros.  -mfix-vr4120 relies on
-     assembler nop insertion.  */
-  cfun->machine->all_noreorder_p = (!current_function_profile
-                                   && !TARGET_FIX_VR4120);
+  cfun->machine->all_noreorder_p = true;
+
+  /* Profiled functions can't be all noreorder because the profiler
+     support uses assembler macros.  */
+  if (current_function_profile)
+    cfun->machine->all_noreorder_p = false;
+
+  /* Code compiled with -mfix-vr4120 can't be all noreorder because
+     we rely on the assembler to work around some errata.  */
+  if (TARGET_FIX_VR4120)
+    cfun->machine->all_noreorder_p = false;
+
+  /* The same is true for -mfix-vr4130 if we might generate mflo or
+     mfhi instructions.  Note that we avoid using mflo and mfhi if
+     the VR4130 macc and dmacc instructions are available instead;
+     see the *mfhilo_{si,di}_macc patterns.  */
+  if (TARGET_FIX_VR4130 && !ISA_HAS_MACCHI)
+    cfun->machine->all_noreorder_p = false;
 
   last_insn = 0;
   hilo_delay = 2;
@@ -8330,7 +9031,7 @@ mips_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
        }
       else if (to == FP_REGS)
        return 4;
-      else if (to == HI_REG || to == LO_REG || to == MD_REGS)
+      else if (reg_class_subset_p (to, ACC_REGS))
        {
          if (TARGET_MIPS16)
            return 12;
@@ -8341,7 +9042,7 @@ mips_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
        {
          return 5;
        }
-    }  /* GR_REG_CLASS_P (from) */
+    }
   else if (from == FP_REGS)
     {
       if (GR_REG_CLASS_P (to))
@@ -8350,8 +9051,8 @@ mips_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
        return 2;
       else if (to == ST_REGS)
        return 8;
-    }  /* from == FP_REGS */
-  else if (from == HI_REG || from == LO_REG || from == MD_REGS)
+    }
+  else if (reg_class_subset_p (from, ACC_REGS))
     {
       if (GR_REG_CLASS_P (to))
        {
@@ -8360,15 +9061,16 @@ mips_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
          else
            return 6;
        }
-    }  /* from == HI_REG, etc.  */
+    }
   else if (from == ST_REGS && GR_REG_CLASS_P (to))
     return 4;
   else if (COP_REG_CLASS_P (from))
     {
       return 5;
-    }  /* COP_REG_CLASS_P (from) */
+    }
 
-  /* Fall through.  */
+  /* Fall through.
+     ??? What cases are these? Shouldn't we return 2 here?  */
 
   return 12;
 }
@@ -8612,7 +9314,7 @@ mips_output_conditional_branch (rtx insn, rtx *operands, int two_operands_p,
             /* Output delay slot instruction.  */
             rtx insn = final_sequence;
             final_scan_insn (XVECEXP (insn, 0, 1), asm_out_file,
-                             optimize, 0, 1, NULL);
+                             optimize, 1, NULL);
             INSN_DELETED_P (XVECEXP (insn, 0, 1)) = 1;
           }
        else
@@ -8631,7 +9333,7 @@ mips_output_conditional_branch (rtx insn, rtx *operands, int two_operands_p,
             /* Output delay slot instruction.  */
             rtx insn = final_sequence;
             final_scan_insn (XVECEXP (insn, 0, 1), asm_out_file,
-                             optimize, 0, 1, NULL);
+                             optimize, 1, NULL);
             INSN_DELETED_P (XVECEXP (insn, 0, 1)) = 1;
           }
        else
@@ -8644,7 +9346,7 @@ mips_output_conditional_branch (rtx insn, rtx *operands, int two_operands_p,
       }
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
   /* NOTREACHED */
@@ -8758,6 +9460,11 @@ mips_output_division (const char *division, rtx *operands)
          output_asm_insn (s, operands);
          s = "bnez\t%2,1f\n\tbreak\t7\n1:";
        }
+      else if (GENERATE_DIVIDE_TRAPS)
+        {
+         output_asm_insn (s, operands);
+         s = "teq\t%2,%.,7";
+        }
       else
        {
          output_asm_insn ("%(bne\t%2,%.,1f", operands);
@@ -8817,15 +9524,13 @@ mips_matching_cpu_name_p (const char *canonical, const char *given)
 }
 
 
-/* Parse an option that takes the name of a processor as its argument.
-   OPTION is the name of the option and CPU_STRING is the argument.
-   Return the corresponding processor enumeration if the CPU_STRING is
-   recognized, otherwise report an error and return null.
+/* Return the mips_cpu_info entry for the processor or ISA given
+   by CPU_STRING.  Return null if the string isn't recognized.
 
    A similar function exists in GAS.  */
 
 static const struct mips_cpu_info *
-mips_parse_cpu (const char *option, const char *cpu_string)
+mips_parse_cpu (const char *cpu_string)
 {
   const struct mips_cpu_info *p;
   const char *s;
@@ -8835,7 +9540,7 @@ mips_parse_cpu (const char *option, const char *cpu_string)
   for (s = cpu_string; *s != 0; s++)
     if (ISUPPER (*s))
       {
-       warning ("the cpu name must be lower case");
+       warning (0, "the cpu name must be lower case");
        break;
       }
 
@@ -8857,7 +9562,6 @@ mips_parse_cpu (const char *option, const char *cpu_string)
     if (mips_matching_cpu_name_p (p->name, cpu_string))
       return p;
 
-  error ("bad value (%s) for %s", cpu_string, option);
   return 0;
 }
 
@@ -9179,9 +9883,6 @@ mips_issue_rate (void)
     default:
       return 1;
     }
-
-  abort ();
-
 }
 
 /* Implements TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD.  This should
@@ -9219,1742 +9920,824 @@ mips_prefetch_cookie (rtx write, rtx locality)
 
 struct builtin_description
 {
-  /* Instruction code.  */
+  /* The code of the main .md file instruction.  See mips_builtin_type
+     for more information.  */
   enum insn_code icode;
-  /* Builtin function name.  */
-  const char *name;              
-  /* Builtin code.  */
-  enum mips_builtins code;       
-  /* Function type.  */
-  enum mips_function_type ftype; 
-  /* The target flag required for this builtin function.  */
-  int target_flags;   
+
+  /* The floating-point comparison code to use with ICODE, if any.  */
+  enum mips_fp_condition cond;
+
+  /* The name of the builtin function.  */
+  const char *name;
+
+  /* Specifies how the function should be expanded.  */
+  enum mips_builtin_type builtin_type;
+
+  /* The function's prototype.  */
+  enum mips_function_type function_type;
+
+  /* The target flags required for this function.  */
+  int target_flags;
 };
 
-/* NOTE: The order of mips_bdesc[] must be the same as the order of
-   enum mips_builtins{} in mips.h.  */
+/* Define a MIPS_BUILTIN_DIRECT function for instruction CODE_FOR_mips_<INSN>.
+   FUNCTION_TYPE and TARGET_FLAGS are builtin_description fields.  */
+#define DIRECT_BUILTIN(INSN, FUNCTION_TYPE, TARGET_FLAGS)              \
+  { CODE_FOR_mips_ ## INSN, 0, "__builtin_mips_" #INSN,                        \
+    MIPS_BUILTIN_DIRECT, FUNCTION_TYPE, TARGET_FLAGS }
+
+/* Define __builtin_mips_<INSN>_<COND>_{s,d}, both of which require
+   TARGET_FLAGS.  */
+#define CMP_SCALAR_BUILTINS(INSN, COND, TARGET_FLAGS)                  \
+  { CODE_FOR_mips_ ## INSN ## _cond_s, MIPS_FP_COND_ ## COND,          \
+    "__builtin_mips_" #INSN "_" #COND "_s",                            \
+    MIPS_BUILTIN_CMP_SINGLE, MIPS_INT_FTYPE_SF_SF, TARGET_FLAGS },     \
+  { CODE_FOR_mips_ ## INSN ## _cond_d, MIPS_FP_COND_ ## COND,          \
+    "__builtin_mips_" #INSN "_" #COND "_d",                            \
+    MIPS_BUILTIN_CMP_SINGLE, MIPS_INT_FTYPE_DF_DF, TARGET_FLAGS }
+
+/* Define __builtin_mips_{any,all,upper,lower}_<INSN>_<COND>_ps.
+   The lower and upper forms require TARGET_FLAGS while the any and all
+   forms require MASK_MIPS3D.  */
+#define CMP_PS_BUILTINS(INSN, COND, TARGET_FLAGS)                      \
+  { CODE_FOR_mips_ ## INSN ## _cond_ps, MIPS_FP_COND_ ## COND,         \
+    "__builtin_mips_any_" #INSN "_" #COND "_ps",                       \
+    MIPS_BUILTIN_CMP_ANY, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },     \
+  { CODE_FOR_mips_ ## INSN ## _cond_ps, MIPS_FP_COND_ ## COND,         \
+    "__builtin_mips_all_" #INSN "_" #COND "_ps",                       \
+    MIPS_BUILTIN_CMP_ALL, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },     \
+  { CODE_FOR_mips_ ## INSN ## _cond_ps, MIPS_FP_COND_ ## COND,         \
+    "__builtin_mips_lower_" #INSN "_" #COND "_ps",                     \
+    MIPS_BUILTIN_CMP_LOWER, MIPS_INT_FTYPE_V2SF_V2SF, TARGET_FLAGS },  \
+  { CODE_FOR_mips_ ## INSN ## _cond_ps, MIPS_FP_COND_ ## COND,         \
+    "__builtin_mips_upper_" #INSN "_" #COND "_ps",                     \
+    MIPS_BUILTIN_CMP_UPPER, MIPS_INT_FTYPE_V2SF_V2SF, TARGET_FLAGS }
+
+/* Define __builtin_mips_{any,all}_<INSN>_<COND>_4s.  The functions
+   require MASK_MIPS3D.  */
+#define CMP_4S_BUILTINS(INSN, COND)                                    \
+  { CODE_FOR_mips_ ## INSN ## _cond_4s, MIPS_FP_COND_ ## COND,         \
+    "__builtin_mips_any_" #INSN "_" #COND "_4s",                       \
+    MIPS_BUILTIN_CMP_ANY, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,          \
+    MASK_MIPS3D },                                                     \
+  { CODE_FOR_mips_ ## INSN ## _cond_4s, MIPS_FP_COND_ ## COND,         \
+    "__builtin_mips_all_" #INSN "_" #COND "_4s",                       \
+    MIPS_BUILTIN_CMP_ALL, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,          \
+    MASK_MIPS3D }
+
+/* Define __builtin_mips_mov{t,f}_<INSN>_<COND>_ps.  The comparison
+   instruction requires TARGET_FLAGS.  */
+#define MOVTF_BUILTINS(INSN, COND, TARGET_FLAGS)                       \
+  { CODE_FOR_mips_ ## INSN ## _cond_ps, MIPS_FP_COND_ ## COND,         \
+    "__builtin_mips_movt_" #INSN "_" #COND "_ps",                      \
+    MIPS_BUILTIN_MOVT, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,            \
+    TARGET_FLAGS },                                                    \
+  { CODE_FOR_mips_ ## INSN ## _cond_ps, MIPS_FP_COND_ ## COND,         \
+    "__builtin_mips_movf_" #INSN "_" #COND "_ps",                      \
+    MIPS_BUILTIN_MOVF, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,            \
+    TARGET_FLAGS }
+
+/* Define all the builtins related to c.cond.fmt condition COND.  */
+#define CMP_BUILTINS(COND)                                             \
+  MOVTF_BUILTINS (c, COND, MASK_PAIRED_SINGLE_FLOAT),                  \
+  MOVTF_BUILTINS (cabs, COND, MASK_MIPS3D),                            \
+  CMP_SCALAR_BUILTINS (cabs, COND, MASK_MIPS3D),                       \
+  CMP_PS_BUILTINS (c, COND, MASK_PAIRED_SINGLE_FLOAT),                 \
+  CMP_PS_BUILTINS (cabs, COND, MASK_MIPS3D),                           \
+  CMP_4S_BUILTINS (c, COND),                                           \
+  CMP_4S_BUILTINS (cabs, COND)
+
+/* __builtin_mips_abs_ps() maps to the standard absM2 pattern.  */
+#define CODE_FOR_mips_abs_ps CODE_FOR_absv2sf2
+
 static const struct builtin_description mips_bdesc[] =
 {
-  { CODE_FOR_mips_pll_ps, "__builtin_mips_pll_ps", MIPS_BUILTIN_PLL_PS,
-    MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_pul_ps, "__builtin_mips_pul_ps", MIPS_BUILTIN_PUL_PS,
-    MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_plu_ps, "__builtin_mips_plu_ps", MIPS_BUILTIN_PLU_PS,
-    MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_puu_ps, "__builtin_mips_puu_ps", MIPS_BUILTIN_PUU_PS,
-    MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_cvt_ps_s, "__builtin_mips_cvt_ps_s", MIPS_BUILTIN_CVT_PS_S,
-    MIPS_V2SF_FTYPE_SF_SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_cvt_s_pl, "__builtin_mips_cvt_s_pl", MIPS_BUILTIN_CVT_S_PL,
-    MIPS_SF_FTYPE_V2SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_cvt_s_pu, "__builtin_mips_cvt_s_pu", MIPS_BUILTIN_CVT_S_PU,
-    MIPS_SF_FTYPE_V2SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_absv2sf2, "__builtin_mips_abs_ps", MIPS_BUILTIN_ABS_PS,
-    MIPS_V2SF_FTYPE_V2SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_alnv_ps, "__builtin_mips_alnv_ps", MIPS_BUILTIN_ALNV_PS,
-    MIPS_V2SF_FTYPE_V2SF_V2SF_INT, MASK_PAIRED_SINGLE },
-
-  { CODE_FOR_mips_addr_ps, "__builtin_mips_addr_ps", MIPS_BUILTIN_ADDR_PS,
-    MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_mulr_ps, "__builtin_mips_mulr_ps", MIPS_BUILTIN_MULR_PS,
-    MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cvt_pw_ps, "__builtin_mips_cvt_pw_ps",
-    MIPS_BUILTIN_CVT_PW_PS, MIPS_V2SF_FTYPE_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cvt_ps_pw, "__builtin_mips_cvt_ps_pw",
-    MIPS_BUILTIN_CVT_PS_PW, MIPS_V2SF_FTYPE_V2SF, MASK_MIPS3D },
-
-  { CODE_FOR_mips_recip1_s, "__builtin_mips_recip1_s", MIPS_BUILTIN_RECIP1_S,
-    MIPS_SF_FTYPE_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_recip1_d, "__builtin_mips_recip1_d", MIPS_BUILTIN_RECIP1_D,
-    MIPS_DF_FTYPE_DF, MASK_MIPS3D },
-  { CODE_FOR_mips_recip1_ps, "__builtin_mips_recip1_ps",
-    MIPS_BUILTIN_RECIP1_PS, MIPS_V2SF_FTYPE_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_recip2_s, "__builtin_mips_recip2_s", MIPS_BUILTIN_RECIP2_S,
-    MIPS_SF_FTYPE_SF_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_recip2_d, "__builtin_mips_recip2_d", MIPS_BUILTIN_RECIP2_D,
-    MIPS_DF_FTYPE_DF_DF, MASK_MIPS3D },
-  { CODE_FOR_mips_recip2_ps, "__builtin_mips_recip2_ps",
-    MIPS_BUILTIN_RECIP2_PS, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-
-  { CODE_FOR_mips_rsqrt1_s, "__builtin_mips_rsqrt1_s", MIPS_BUILTIN_RSQRT1_S,
-    MIPS_SF_FTYPE_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_rsqrt1_d, "__builtin_mips_rsqrt1_d", MIPS_BUILTIN_RSQRT1_D,
-    MIPS_DF_FTYPE_DF, MASK_MIPS3D },
-  { CODE_FOR_mips_rsqrt1_ps, "__builtin_mips_rsqrt1_ps",
-    MIPS_BUILTIN_RSQRT1_PS, MIPS_V2SF_FTYPE_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_rsqrt2_s, "__builtin_mips_rsqrt2_s", MIPS_BUILTIN_RSQRT2_S,
-    MIPS_SF_FTYPE_SF_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_rsqrt2_d, "__builtin_mips_rsqrt2_d", MIPS_BUILTIN_RSQRT2_D,
-    MIPS_DF_FTYPE_DF_DF, MASK_MIPS3D },
-  { CODE_FOR_mips_rsqrt2_ps, "__builtin_mips_rsqrt2_ps",
-    MIPS_BUILTIN_RSQRT2_PS, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-
-  { CODE_FOR_mips_c_f_ps, "__builtin_mips_any_c_f_ps", MIPS_BUILTIN_ANY_C_F_PS,
-    MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_f_ps, "__builtin_mips_upper_c_f_ps",
-    MIPS_BUILTIN_UPPER_C_F_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_f_ps, "__builtin_mips_lower_c_f_ps",
-    MIPS_BUILTIN_LOWER_C_F_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_f_ps, "__builtin_mips_all_c_f_ps", MIPS_BUILTIN_ALL_C_F_PS,
-    MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_un_ps, "__builtin_mips_any_c_un_ps",
-    MIPS_BUILTIN_ANY_C_UN_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_un_ps, "__builtin_mips_upper_c_un_ps",
-    MIPS_BUILTIN_UPPER_C_UN_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_un_ps, "__builtin_mips_lower_c_un_ps",
-    MIPS_BUILTIN_LOWER_C_UN_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_un_ps, "__builtin_mips_all_c_un_ps",
-    MIPS_BUILTIN_ALL_C_UN_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_eq_ps, "__builtin_mips_any_c_eq_ps",
-    MIPS_BUILTIN_ANY_C_EQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_eq_ps, "__builtin_mips_upper_c_eq_ps",
-    MIPS_BUILTIN_UPPER_C_EQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_eq_ps, "__builtin_mips_lower_c_eq_ps",
-    MIPS_BUILTIN_LOWER_C_EQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_eq_ps, "__builtin_mips_all_c_eq_ps",
-    MIPS_BUILTIN_ALL_C_EQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_ueq_ps, "__builtin_mips_any_c_ueq_ps",
-    MIPS_BUILTIN_ANY_C_UEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_ueq_ps, "__builtin_mips_upper_c_ueq_ps",
-    MIPS_BUILTIN_UPPER_C_UEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ueq_ps, "__builtin_mips_lower_c_ueq_ps",
-    MIPS_BUILTIN_LOWER_C_UEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ueq_ps, "__builtin_mips_all_c_ueq_ps",
-    MIPS_BUILTIN_ALL_C_UEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_olt_ps, "__builtin_mips_any_c_olt_ps",
-    MIPS_BUILTIN_ANY_C_OLT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_olt_ps, "__builtin_mips_upper_c_olt_ps",
-    MIPS_BUILTIN_UPPER_C_OLT_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_olt_ps, "__builtin_mips_lower_c_olt_ps",
-    MIPS_BUILTIN_LOWER_C_OLT_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_olt_ps, "__builtin_mips_all_c_olt_ps",
-    MIPS_BUILTIN_ALL_C_OLT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_ult_ps, "__builtin_mips_any_c_ult_ps",
-    MIPS_BUILTIN_ANY_C_ULT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_ult_ps, "__builtin_mips_upper_c_ult_ps",
-    MIPS_BUILTIN_UPPER_C_ULT_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ult_ps, "__builtin_mips_lower_c_ult_ps",
-    MIPS_BUILTIN_LOWER_C_ULT_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ult_ps, "__builtin_mips_all_c_ult_ps",
-    MIPS_BUILTIN_ALL_C_ULT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_ole_ps, "__builtin_mips_any_c_ole_ps",
-    MIPS_BUILTIN_ANY_C_OLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_ole_ps, "__builtin_mips_upper_c_ole_ps",
-    MIPS_BUILTIN_UPPER_C_OLE_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ole_ps, "__builtin_mips_lower_c_ole_ps",
-    MIPS_BUILTIN_LOWER_C_OLE_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ole_ps, "__builtin_mips_all_c_ole_ps",
-    MIPS_BUILTIN_ALL_C_OLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_ule_ps, "__builtin_mips_any_c_ule_ps",
-    MIPS_BUILTIN_ANY_C_ULE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_ule_ps, "__builtin_mips_upper_c_ule_ps",
-    MIPS_BUILTIN_UPPER_C_ULE_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ule_ps, "__builtin_mips_lower_c_ule_ps",
-    MIPS_BUILTIN_LOWER_C_ULE_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ule_ps, "__builtin_mips_all_c_ule_ps",
-    MIPS_BUILTIN_ALL_C_ULE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_sf_ps, "__builtin_mips_any_c_sf_ps",
-    MIPS_BUILTIN_ANY_C_SF_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_sf_ps, "__builtin_mips_upper_c_sf_ps",
-    MIPS_BUILTIN_UPPER_C_SF_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_sf_ps, "__builtin_mips_lower_c_sf_ps",
-    MIPS_BUILTIN_LOWER_C_SF_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_sf_ps, "__builtin_mips_all_c_sf_ps",
-    MIPS_BUILTIN_ALL_C_SF_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_ngle_ps, "__builtin_mips_any_c_ngle_ps",
-    MIPS_BUILTIN_ANY_C_NGLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_ngle_ps, "__builtin_mips_upper_c_ngle_ps",
-    MIPS_BUILTIN_UPPER_C_NGLE_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ngle_ps, "__builtin_mips_lower_c_ngle_ps",
-    MIPS_BUILTIN_LOWER_C_NGLE_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ngle_ps, "__builtin_mips_all_c_ngle_ps",
-    MIPS_BUILTIN_ALL_C_NGLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_seq_ps, "__builtin_mips_any_c_seq_ps",
-    MIPS_BUILTIN_ANY_C_SEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_seq_ps, "__builtin_mips_upper_c_seq_ps",
-    MIPS_BUILTIN_UPPER_C_SEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_seq_ps, "__builtin_mips_lower_c_seq_ps",
-    MIPS_BUILTIN_LOWER_C_SEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_seq_ps, "__builtin_mips_all_c_seq_ps",
-    MIPS_BUILTIN_ALL_C_SEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_ngl_ps, "__builtin_mips_any_c_ngl_ps",
-    MIPS_BUILTIN_ANY_C_NGL_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_ngl_ps, "__builtin_mips_upper_c_ngl_ps",
-    MIPS_BUILTIN_UPPER_C_NGL_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ngl_ps, "__builtin_mips_lower_c_ngl_ps",
-    MIPS_BUILTIN_LOWER_C_NGL_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ngl_ps, "__builtin_mips_all_c_ngl_ps",
-    MIPS_BUILTIN_ALL_C_NGL_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_lt_ps, "__builtin_mips_any_c_lt_ps",
-    MIPS_BUILTIN_ANY_C_LT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_lt_ps, "__builtin_mips_upper_c_lt_ps",
-    MIPS_BUILTIN_UPPER_C_LT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_lt_ps, "__builtin_mips_lower_c_lt_ps",
-    MIPS_BUILTIN_LOWER_C_LT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_lt_ps, "__builtin_mips_all_c_lt_ps",
-    MIPS_BUILTIN_ALL_C_LT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_nge_ps, "__builtin_mips_any_c_nge_ps",
-    MIPS_BUILTIN_ANY_C_NGE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_nge_ps, "__builtin_mips_upper_c_nge_ps",
-    MIPS_BUILTIN_UPPER_C_NGE_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_nge_ps, "__builtin_mips_lower_c_nge_ps",
-    MIPS_BUILTIN_LOWER_C_NGE_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_nge_ps, "__builtin_mips_all_c_nge_ps",
-    MIPS_BUILTIN_ALL_C_NGE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_le_ps, "__builtin_mips_any_c_le_ps",
-    MIPS_BUILTIN_ANY_C_LE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_le_ps, "__builtin_mips_upper_c_le_ps",
-    MIPS_BUILTIN_UPPER_C_LE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_le_ps, "__builtin_mips_lower_c_le_ps",
-    MIPS_BUILTIN_LOWER_C_LE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_le_ps, "__builtin_mips_all_c_le_ps",
-    MIPS_BUILTIN_ALL_C_LE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_ngt_ps, "__builtin_mips_any_c_ngt_ps",
-    MIPS_BUILTIN_ANY_C_NGT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_ngt_ps, "__builtin_mips_upper_c_ngt_ps",
-    MIPS_BUILTIN_UPPER_C_NGT_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ngt_ps, "__builtin_mips_lower_c_ngt_ps",
-    MIPS_BUILTIN_LOWER_C_NGT_PS, MIPS_INT_FTYPE_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ngt_ps, "__builtin_mips_all_c_ngt_ps",
-    MIPS_BUILTIN_ALL_C_NGT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-
-  { CODE_FOR_mips_cabs_f_ps, "__builtin_mips_any_cabs_f_ps",
-    MIPS_BUILTIN_ANY_CABS_F_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_f_ps, "__builtin_mips_upper_cabs_f_ps",
-    MIPS_BUILTIN_UPPER_CABS_F_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_f_ps, "__builtin_mips_lower_cabs_f_ps",
-    MIPS_BUILTIN_LOWER_CABS_F_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_f_ps, "__builtin_mips_all_cabs_f_ps",
-    MIPS_BUILTIN_ALL_CABS_F_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_un_ps, "__builtin_mips_any_cabs_un_ps",
-    MIPS_BUILTIN_ANY_CABS_UN_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_un_ps, "__builtin_mips_upper_cabs_un_ps",
-    MIPS_BUILTIN_UPPER_CABS_UN_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_un_ps, "__builtin_mips_lower_cabs_un_ps",
-    MIPS_BUILTIN_LOWER_CABS_UN_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_un_ps, "__builtin_mips_all_cabs_un_ps",
-    MIPS_BUILTIN_ALL_CABS_UN_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_eq_ps, "__builtin_mips_any_cabs_eq_ps",
-    MIPS_BUILTIN_ANY_CABS_EQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_eq_ps, "__builtin_mips_upper_cabs_eq_ps",
-    MIPS_BUILTIN_UPPER_CABS_EQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_eq_ps, "__builtin_mips_lower_cabs_eq_ps",
-    MIPS_BUILTIN_LOWER_CABS_EQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_eq_ps, "__builtin_mips_all_cabs_eq_ps",
-    MIPS_BUILTIN_ALL_CABS_EQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ueq_ps, "__builtin_mips_any_cabs_ueq_ps",
-    MIPS_BUILTIN_ANY_CABS_UEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ueq_ps, "__builtin_mips_upper_cabs_ueq_ps",
-    MIPS_BUILTIN_UPPER_CABS_UEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ueq_ps, "__builtin_mips_lower_cabs_ueq_ps",
-    MIPS_BUILTIN_LOWER_CABS_UEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ueq_ps, "__builtin_mips_all_cabs_ueq_ps",
-    MIPS_BUILTIN_ALL_CABS_UEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_olt_ps, "__builtin_mips_any_cabs_olt_ps",
-    MIPS_BUILTIN_ANY_CABS_OLT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_olt_ps, "__builtin_mips_upper_cabs_olt_ps",
-    MIPS_BUILTIN_UPPER_CABS_OLT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_olt_ps, "__builtin_mips_lower_cabs_olt_ps",
-    MIPS_BUILTIN_LOWER_CABS_OLT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_olt_ps, "__builtin_mips_all_cabs_olt_ps",
-    MIPS_BUILTIN_ALL_CABS_OLT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ult_ps, "__builtin_mips_any_cabs_ult_ps",
-    MIPS_BUILTIN_ANY_CABS_ULT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ult_ps, "__builtin_mips_upper_cabs_ult_ps",
-    MIPS_BUILTIN_UPPER_CABS_ULT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ult_ps, "__builtin_mips_lower_cabs_ult_ps",
-    MIPS_BUILTIN_LOWER_CABS_ULT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ult_ps, "__builtin_mips_all_cabs_ult_ps",
-    MIPS_BUILTIN_ALL_CABS_ULT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ole_ps, "__builtin_mips_any_cabs_ole_ps",
-    MIPS_BUILTIN_ANY_CABS_OLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ole_ps, "__builtin_mips_upper_cabs_ole_ps",
-    MIPS_BUILTIN_UPPER_CABS_OLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ole_ps, "__builtin_mips_lower_cabs_ole_ps",
-    MIPS_BUILTIN_LOWER_CABS_OLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ole_ps, "__builtin_mips_all_cabs_ole_ps",
-    MIPS_BUILTIN_ALL_CABS_OLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ule_ps, "__builtin_mips_any_cabs_ule_ps",
-    MIPS_BUILTIN_ANY_CABS_ULE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ule_ps, "__builtin_mips_upper_cabs_ule_ps",
-    MIPS_BUILTIN_UPPER_CABS_ULE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ule_ps, "__builtin_mips_lower_cabs_ule_ps",
-    MIPS_BUILTIN_LOWER_CABS_ULE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ule_ps, "__builtin_mips_all_cabs_ule_ps",
-    MIPS_BUILTIN_ALL_CABS_ULE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_sf_ps, "__builtin_mips_any_cabs_sf_ps",
-    MIPS_BUILTIN_ANY_CABS_SF_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_sf_ps, "__builtin_mips_upper_cabs_sf_ps",
-    MIPS_BUILTIN_UPPER_CABS_SF_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_sf_ps, "__builtin_mips_lower_cabs_sf_ps",
-    MIPS_BUILTIN_LOWER_CABS_SF_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_sf_ps, "__builtin_mips_all_cabs_sf_ps",
-    MIPS_BUILTIN_ALL_CABS_SF_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngle_ps, "__builtin_mips_any_cabs_ngle_ps",
-    MIPS_BUILTIN_ANY_CABS_NGLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngle_ps, "__builtin_mips_upper_cabs_ngle_ps",
-    MIPS_BUILTIN_UPPER_CABS_NGLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngle_ps, "__builtin_mips_lower_cabs_ngle_ps",
-    MIPS_BUILTIN_LOWER_CABS_NGLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngle_ps, "__builtin_mips_all_cabs_ngle_ps",
-    MIPS_BUILTIN_ALL_CABS_NGLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_seq_ps, "__builtin_mips_any_cabs_seq_ps",
-    MIPS_BUILTIN_ANY_CABS_SEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_seq_ps, "__builtin_mips_upper_cabs_seq_ps",
-    MIPS_BUILTIN_UPPER_CABS_SEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_seq_ps, "__builtin_mips_lower_cabs_seq_ps",
-    MIPS_BUILTIN_LOWER_CABS_SEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_seq_ps, "__builtin_mips_all_cabs_seq_ps",
-    MIPS_BUILTIN_ALL_CABS_SEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngl_ps, "__builtin_mips_any_cabs_ngl_ps",
-    MIPS_BUILTIN_ANY_CABS_NGL_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngl_ps, "__builtin_mips_upper_cabs_ngl_ps",
-    MIPS_BUILTIN_UPPER_CABS_NGL_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngl_ps, "__builtin_mips_lower_cabs_ngl_ps",
-    MIPS_BUILTIN_LOWER_CABS_NGL_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngl_ps, "__builtin_mips_all_cabs_ngl_ps",
-    MIPS_BUILTIN_ALL_CABS_NGL_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_lt_ps, "__builtin_mips_any_cabs_lt_ps",
-    MIPS_BUILTIN_ANY_CABS_LT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_lt_ps, "__builtin_mips_upper_cabs_lt_ps",
-    MIPS_BUILTIN_UPPER_CABS_LT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_lt_ps, "__builtin_mips_lower_cabs_lt_ps",
-    MIPS_BUILTIN_LOWER_CABS_LT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_lt_ps, "__builtin_mips_all_cabs_lt_ps",
-    MIPS_BUILTIN_ALL_CABS_LT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_nge_ps, "__builtin_mips_any_cabs_nge_ps",
-    MIPS_BUILTIN_ANY_CABS_NGE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_nge_ps, "__builtin_mips_upper_cabs_nge_ps",
-    MIPS_BUILTIN_UPPER_CABS_NGE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_nge_ps, "__builtin_mips_lower_cabs_nge_ps",
-    MIPS_BUILTIN_LOWER_CABS_NGE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_nge_ps, "__builtin_mips_all_cabs_nge_ps",
-    MIPS_BUILTIN_ALL_CABS_NGE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_le_ps, "__builtin_mips_any_cabs_le_ps",
-    MIPS_BUILTIN_ANY_CABS_LE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_le_ps, "__builtin_mips_upper_cabs_le_ps",
-    MIPS_BUILTIN_UPPER_CABS_LE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_le_ps, "__builtin_mips_lower_cabs_le_ps",
-    MIPS_BUILTIN_LOWER_CABS_LE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_le_ps, "__builtin_mips_all_cabs_le_ps",
-    MIPS_BUILTIN_ALL_CABS_LE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngt_ps, "__builtin_mips_any_cabs_ngt_ps",
-    MIPS_BUILTIN_ANY_CABS_NGT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngt_ps, "__builtin_mips_upper_cabs_ngt_ps",
-    MIPS_BUILTIN_UPPER_CABS_NGT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngt_ps, "__builtin_mips_lower_cabs_ngt_ps",
-    MIPS_BUILTIN_LOWER_CABS_NGT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngt_ps, "__builtin_mips_all_cabs_ngt_ps",
-    MIPS_BUILTIN_ALL_CABS_NGT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
-
-  { CODE_FOR_mips_c_f_4s, "__builtin_mips_any_c_f_4s",
-    MIPS_BUILTIN_ANY_C_F_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_f_4s, "__builtin_mips_all_c_f_4s",
-    MIPS_BUILTIN_ALL_C_F_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF, MASK_MIPS3D },
-  { CODE_FOR_mips_c_un_4s, "__builtin_mips_any_c_un_4s",
-    MIPS_BUILTIN_ANY_C_UN_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_un_4s, "__builtin_mips_all_c_un_4s",
-    MIPS_BUILTIN_ALL_C_UN_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_eq_4s, "__builtin_mips_any_c_eq_4s",
-    MIPS_BUILTIN_ANY_C_EQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_eq_4s, "__builtin_mips_all_c_eq_4s",
-    MIPS_BUILTIN_ALL_C_EQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_ueq_4s, "__builtin_mips_any_c_ueq_4s",
-    MIPS_BUILTIN_ANY_C_UEQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_ueq_4s, "__builtin_mips_all_c_ueq_4s",
-    MIPS_BUILTIN_ALL_C_UEQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_olt_4s, "__builtin_mips_any_c_olt_4s",
-    MIPS_BUILTIN_ANY_C_OLT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_olt_4s, "__builtin_mips_all_c_olt_4s",
-    MIPS_BUILTIN_ALL_C_OLT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_ult_4s, "__builtin_mips_any_c_ult_4s",
-    MIPS_BUILTIN_ANY_C_ULT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_ult_4s, "__builtin_mips_all_c_ult_4s",
-    MIPS_BUILTIN_ALL_C_ULT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_ole_4s, "__builtin_mips_any_c_ole_4s",
-    MIPS_BUILTIN_ANY_C_OLE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_ole_4s, "__builtin_mips_all_c_ole_4s",
-    MIPS_BUILTIN_ALL_C_OLE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_ule_4s, "__builtin_mips_any_c_ule_4s",
-    MIPS_BUILTIN_ANY_C_ULE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_ule_4s, "__builtin_mips_all_c_ule_4s",
-    MIPS_BUILTIN_ALL_C_ULE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_sf_4s, "__builtin_mips_any_c_sf_4s",
-    MIPS_BUILTIN_ANY_C_SF_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_sf_4s, "__builtin_mips_all_c_sf_4s",
-    MIPS_BUILTIN_ALL_C_SF_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_ngle_4s, "__builtin_mips_any_c_ngle_4s",
-    MIPS_BUILTIN_ANY_C_NGLE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_ngle_4s, "__builtin_mips_all_c_ngle_4s",
-    MIPS_BUILTIN_ALL_C_NGLE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_seq_4s, "__builtin_mips_any_c_seq_4s",
-    MIPS_BUILTIN_ANY_C_SEQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_seq_4s, "__builtin_mips_all_c_seq_4s",
-    MIPS_BUILTIN_ALL_C_SEQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_ngl_4s, "__builtin_mips_any_c_ngl_4s",
-    MIPS_BUILTIN_ANY_C_NGL_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_ngl_4s, "__builtin_mips_all_c_ngl_4s",
-    MIPS_BUILTIN_ALL_C_NGL_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_lt_4s, "__builtin_mips_any_c_lt_4s",
-    MIPS_BUILTIN_ANY_C_LT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_lt_4s, "__builtin_mips_all_c_lt_4s",
-    MIPS_BUILTIN_ALL_C_LT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_nge_4s, "__builtin_mips_any_c_nge_4s",
-    MIPS_BUILTIN_ANY_C_NGE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_nge_4s, "__builtin_mips_all_c_nge_4s",
-    MIPS_BUILTIN_ALL_C_NGE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_le_4s, "__builtin_mips_any_c_le_4s",
-    MIPS_BUILTIN_ANY_C_LE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_le_4s, "__builtin_mips_all_c_le_4s",
-    MIPS_BUILTIN_ALL_C_LE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_ngt_4s, "__builtin_mips_any_c_ngt_4s",
-    MIPS_BUILTIN_ANY_C_NGT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_ngt_4s, "__builtin_mips_all_c_ngt_4s",
-    MIPS_BUILTIN_ALL_C_NGT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-
-  { CODE_FOR_mips_cabs_f_4s, "__builtin_mips_any_cabs_f_4s",
-    MIPS_BUILTIN_ANY_CABS_F_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_f_4s, "__builtin_mips_all_cabs_f_4s",
-    MIPS_BUILTIN_ALL_CABS_F_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_un_4s, "__builtin_mips_any_cabs_un_4s",
-    MIPS_BUILTIN_ANY_CABS_UN_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_un_4s, "__builtin_mips_all_cabs_un_4s",
-    MIPS_BUILTIN_ALL_CABS_UN_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_eq_4s, "__builtin_mips_any_cabs_eq_4s",
-    MIPS_BUILTIN_ANY_CABS_EQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_eq_4s, "__builtin_mips_all_cabs_eq_4s",
-    MIPS_BUILTIN_ALL_CABS_EQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ueq_4s, "__builtin_mips_any_cabs_ueq_4s",
-    MIPS_BUILTIN_ANY_CABS_UEQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ueq_4s, "__builtin_mips_all_cabs_ueq_4s",
-    MIPS_BUILTIN_ALL_CABS_UEQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_olt_4s, "__builtin_mips_any_cabs_olt_4s",
-    MIPS_BUILTIN_ANY_CABS_OLT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_olt_4s, "__builtin_mips_all_cabs_olt_4s",
-    MIPS_BUILTIN_ALL_CABS_OLT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ult_4s, "__builtin_mips_any_cabs_ult_4s",
-    MIPS_BUILTIN_ANY_CABS_ULT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ult_4s, "__builtin_mips_all_cabs_ult_4s",
-    MIPS_BUILTIN_ALL_CABS_ULT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ole_4s, "__builtin_mips_any_cabs_ole_4s",
-    MIPS_BUILTIN_ANY_CABS_OLE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ole_4s, "__builtin_mips_all_cabs_ole_4s",
-    MIPS_BUILTIN_ALL_CABS_OLE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ule_4s, "__builtin_mips_any_cabs_ule_4s",
-    MIPS_BUILTIN_ANY_CABS_ULE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ule_4s, "__builtin_mips_all_cabs_ule_4s",
-    MIPS_BUILTIN_ALL_CABS_ULE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_sf_4s, "__builtin_mips_any_cabs_sf_4s",
-    MIPS_BUILTIN_ANY_CABS_SF_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_sf_4s, "__builtin_mips_all_cabs_sf_4s",
-    MIPS_BUILTIN_ALL_CABS_SF_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngle_4s, "__builtin_mips_any_cabs_ngle_4s",
-    MIPS_BUILTIN_ANY_CABS_NGLE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngle_4s, "__builtin_mips_all_cabs_ngle_4s",
-    MIPS_BUILTIN_ALL_CABS_NGLE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_seq_4s, "__builtin_mips_any_cabs_seq_4s",
-    MIPS_BUILTIN_ANY_CABS_SEQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_seq_4s, "__builtin_mips_all_cabs_seq_4s",
-    MIPS_BUILTIN_ALL_CABS_SEQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngl_4s, "__builtin_mips_any_cabs_ngl_4s",
-    MIPS_BUILTIN_ANY_CABS_NGL_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngl_4s, "__builtin_mips_all_cabs_ngl_4s",
-    MIPS_BUILTIN_ALL_CABS_NGL_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_lt_4s, "__builtin_mips_any_cabs_lt_4s",
-    MIPS_BUILTIN_ANY_CABS_LT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_lt_4s, "__builtin_mips_all_cabs_lt_4s",
-    MIPS_BUILTIN_ALL_CABS_LT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_nge_4s, "__builtin_mips_any_cabs_nge_4s",
-    MIPS_BUILTIN_ANY_CABS_NGE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_nge_4s, "__builtin_mips_all_cabs_nge_4s",
-    MIPS_BUILTIN_ALL_CABS_NGE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_le_4s, "__builtin_mips_any_cabs_le_4s",
-    MIPS_BUILTIN_ANY_CABS_LE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_le_4s, "__builtin_mips_all_cabs_le_4s",
-    MIPS_BUILTIN_ALL_CABS_LE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngt_4s, "__builtin_mips_any_cabs_ngt_4s",
-    MIPS_BUILTIN_ANY_CABS_NGT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngt_4s, "__builtin_mips_all_cabs_ngt_4s",
-    MIPS_BUILTIN_ALL_CABS_NGT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-
-  { CODE_FOR_mips_cabs_f_s, "__builtin_mips_cabs_f_s",
-    MIPS_BUILTIN_CABS_F_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_un_s, "__builtin_mips_cabs_un_s",
-    MIPS_BUILTIN_CABS_UN_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_eq_s, "__builtin_mips_cabs_eq_s",
-    MIPS_BUILTIN_CABS_EQ_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ueq_s, "__builtin_mips_cabs_ueq_s",
-    MIPS_BUILTIN_CABS_UEQ_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_olt_s, "__builtin_mips_cabs_olt_s",
-    MIPS_BUILTIN_CABS_OLT_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ult_s, "__builtin_mips_cabs_ult_s",
-    MIPS_BUILTIN_CABS_ULT_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ole_s, "__builtin_mips_cabs_ole_s",
-    MIPS_BUILTIN_CABS_OLE_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ule_s, "__builtin_mips_cabs_ule_s",
-    MIPS_BUILTIN_CABS_ULE_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_sf_s, "__builtin_mips_cabs_sf_s",
-    MIPS_BUILTIN_CABS_SF_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngle_s, "__builtin_mips_cabs_ngle_s",
-    MIPS_BUILTIN_CABS_NGLE_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_seq_s, "__builtin_mips_cabs_seq_s",
-    MIPS_BUILTIN_CABS_SEQ_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngl_s, "__builtin_mips_cabs_ngl_s",
-    MIPS_BUILTIN_CABS_NGL_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_lt_s, "__builtin_mips_cabs_lt_s",
-    MIPS_BUILTIN_CABS_LT_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_nge_s, "__builtin_mips_cabs_nge_s",
-    MIPS_BUILTIN_CABS_NGE_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_le_s, "__builtin_mips_cabs_le_s",
-    MIPS_BUILTIN_CABS_LE_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngt_s, "__builtin_mips_cabs_ngt_s",
-    MIPS_BUILTIN_CABS_NGT_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_f_d, "__builtin_mips_cabs_f_d",
-    MIPS_BUILTIN_CABS_F_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_un_d, "__builtin_mips_cabs_un_d",
-    MIPS_BUILTIN_CABS_UN_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_eq_d, "__builtin_mips_cabs_eq_d",
-    MIPS_BUILTIN_CABS_EQ_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ueq_d, "__builtin_mips_cabs_ueq_d",
-    MIPS_BUILTIN_CABS_UEQ_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_olt_d, "__builtin_mips_cabs_olt_d",
-    MIPS_BUILTIN_CABS_OLT_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ult_d, "__builtin_mips_cabs_ult_d",
-    MIPS_BUILTIN_CABS_ULT_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ole_d, "__builtin_mips_cabs_ole_d",
-    MIPS_BUILTIN_CABS_OLE_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ule_d, "__builtin_mips_cabs_ule_d",
-    MIPS_BUILTIN_CABS_ULE_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_sf_d, "__builtin_mips_cabs_sf_d",
-    MIPS_BUILTIN_CABS_SF_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngle_d, "__builtin_mips_cabs_ngle_d",
-    MIPS_BUILTIN_CABS_NGLE_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_seq_d, "__builtin_mips_cabs_seq_d",
-    MIPS_BUILTIN_CABS_SEQ_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngl_d, "__builtin_mips_cabs_ngl_d",
-    MIPS_BUILTIN_CABS_NGL_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_lt_d, "__builtin_mips_cabs_lt_d",
-    MIPS_BUILTIN_CABS_LT_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_nge_d, "__builtin_mips_cabs_nge_d",
-    MIPS_BUILTIN_CABS_NGE_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_le_d, "__builtin_mips_cabs_le_d",
-    MIPS_BUILTIN_CABS_LE_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngt_d, "__builtin_mips_cabs_ngt_d",
-    MIPS_BUILTIN_CABS_NGT_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
-
-  { CODE_FOR_mips_c_f_ps, "__builtin_mips_movt_c_f_ps",
-    MIPS_BUILTIN_MOVT_C_F_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_un_ps, "__builtin_mips_movt_c_un_ps",
-    MIPS_BUILTIN_MOVT_C_UN_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_eq_ps, "__builtin_mips_movt_c_eq_ps",
-    MIPS_BUILTIN_MOVT_C_EQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ueq_ps, "__builtin_mips_movt_c_ueq_ps",
-    MIPS_BUILTIN_MOVT_C_UEQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_olt_ps, "__builtin_mips_movt_c_olt_ps",
-    MIPS_BUILTIN_MOVT_C_OLT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ult_ps, "__builtin_mips_movt_c_ult_ps",
-    MIPS_BUILTIN_MOVT_C_ULT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ole_ps, "__builtin_mips_movt_c_ole_ps",
-    MIPS_BUILTIN_MOVT_C_OLE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ule_ps, "__builtin_mips_movt_c_ule_ps",
-    MIPS_BUILTIN_MOVT_C_ULE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_sf_ps, "__builtin_mips_movt_c_sf_ps",
-    MIPS_BUILTIN_MOVT_C_SF_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ngle_ps, "__builtin_mips_movt_c_ngle_ps",
-    MIPS_BUILTIN_MOVT_C_NGLE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_seq_ps, "__builtin_mips_movt_c_seq_ps",
-    MIPS_BUILTIN_MOVT_C_SEQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ngl_ps, "__builtin_mips_movt_c_ngl_ps",
-    MIPS_BUILTIN_MOVT_C_NGL_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_lt_ps, "__builtin_mips_movt_c_lt_ps",
-    MIPS_BUILTIN_MOVT_C_LT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_nge_ps, "__builtin_mips_movt_c_nge_ps",
-    MIPS_BUILTIN_MOVT_C_NGE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_le_ps, "__builtin_mips_movt_c_le_ps",
-    MIPS_BUILTIN_MOVT_C_LE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ngt_ps, "__builtin_mips_movt_c_ngt_ps",
-    MIPS_BUILTIN_MOVT_C_NGT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_cabs_f_ps, "__builtin_mips_movt_cabs_f_ps",
-    MIPS_BUILTIN_MOVT_CABS_F_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_un_ps, "__builtin_mips_movt_cabs_un_ps",
-    MIPS_BUILTIN_MOVT_CABS_UN_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_eq_ps, "__builtin_mips_movt_cabs_eq_ps",
-    MIPS_BUILTIN_MOVT_CABS_EQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ueq_ps, "__builtin_mips_movt_cabs_ueq_ps",
-    MIPS_BUILTIN_MOVT_CABS_UEQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_olt_ps, "__builtin_mips_movt_cabs_olt_ps",
-    MIPS_BUILTIN_MOVT_CABS_OLT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ult_ps, "__builtin_mips_movt_cabs_ult_ps",
-    MIPS_BUILTIN_MOVT_CABS_ULT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ole_ps, "__builtin_mips_movt_cabs_ole_ps",
-    MIPS_BUILTIN_MOVT_CABS_OLE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ule_ps, "__builtin_mips_movt_cabs_ule_ps",
-    MIPS_BUILTIN_MOVT_CABS_ULE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_sf_ps, "__builtin_mips_movt_cabs_sf_ps",
-    MIPS_BUILTIN_MOVT_CABS_SF_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngle_ps, "__builtin_mips_movt_cabs_ngle_ps",
-    MIPS_BUILTIN_MOVT_CABS_NGLE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_seq_ps, "__builtin_mips_movt_cabs_seq_ps",
-    MIPS_BUILTIN_MOVT_CABS_SEQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngl_ps, "__builtin_mips_movt_cabs_ngl_ps",
-    MIPS_BUILTIN_MOVT_CABS_NGL_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_lt_ps, "__builtin_mips_movt_cabs_lt_ps",
-    MIPS_BUILTIN_MOVT_CABS_LT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_nge_ps, "__builtin_mips_movt_cabs_nge_ps",
-    MIPS_BUILTIN_MOVT_CABS_NGE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_le_ps, "__builtin_mips_movt_cabs_le_ps",
-    MIPS_BUILTIN_MOVT_CABS_LE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngt_ps, "__builtin_mips_movt_cabs_ngt_ps",
-    MIPS_BUILTIN_MOVT_CABS_NGT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_c_f_ps, "__builtin_mips_movf_c_f_ps",
-    MIPS_BUILTIN_MOVF_C_F_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_un_ps, "__builtin_mips_movf_c_un_ps",
-    MIPS_BUILTIN_MOVF_C_UN_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_eq_ps, "__builtin_mips_movf_c_eq_ps",
-    MIPS_BUILTIN_MOVF_C_EQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ueq_ps, "__builtin_mips_movf_c_ueq_ps",
-    MIPS_BUILTIN_MOVF_C_UEQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_olt_ps, "__builtin_mips_movf_c_olt_ps",
-    MIPS_BUILTIN_MOVF_C_OLT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ult_ps, "__builtin_mips_movf_c_ult_ps",
-    MIPS_BUILTIN_MOVF_C_ULT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ole_ps, "__builtin_mips_movf_c_ole_ps",
-    MIPS_BUILTIN_MOVF_C_OLE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ule_ps, "__builtin_mips_movf_c_ule_ps",
-    MIPS_BUILTIN_MOVF_C_ULE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_sf_ps, "__builtin_mips_movf_c_sf_ps",
-    MIPS_BUILTIN_MOVF_C_SF_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ngle_ps, "__builtin_mips_movf_c_ngle_ps",
-    MIPS_BUILTIN_MOVF_C_NGLE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_seq_ps, "__builtin_mips_movf_c_seq_ps",
-    MIPS_BUILTIN_MOVF_C_SEQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ngl_ps, "__builtin_mips_movf_c_ngl_ps",
-    MIPS_BUILTIN_MOVF_C_NGL_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_lt_ps, "__builtin_mips_movf_c_lt_ps",
-    MIPS_BUILTIN_MOVF_C_LT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_nge_ps, "__builtin_mips_movf_c_nge_ps",
-    MIPS_BUILTIN_MOVF_C_NGE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_le_ps, "__builtin_mips_movf_c_le_ps",
-    MIPS_BUILTIN_MOVF_C_LE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_c_ngt_ps, "__builtin_mips_movf_c_ngt_ps",
-    MIPS_BUILTIN_MOVF_C_NGT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_PAIRED_SINGLE },
-  { CODE_FOR_mips_cabs_f_ps, "__builtin_mips_movf_cabs_f_ps",
-    MIPS_BUILTIN_MOVF_CABS_F_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_un_ps, "__builtin_mips_movf_cabs_un_ps",
-    MIPS_BUILTIN_MOVF_CABS_UN_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_eq_ps, "__builtin_mips_movf_cabs_eq_ps",
-    MIPS_BUILTIN_MOVF_CABS_EQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ueq_ps, "__builtin_mips_movf_cabs_ueq_ps",
-    MIPS_BUILTIN_MOVF_CABS_UEQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_olt_ps, "__builtin_mips_movf_cabs_olt_ps",
-    MIPS_BUILTIN_MOVF_CABS_OLT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ult_ps, "__builtin_mips_movf_cabs_ult_ps",
-    MIPS_BUILTIN_MOVF_CABS_ULT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ole_ps, "__builtin_mips_movf_cabs_ole_ps",
-    MIPS_BUILTIN_MOVF_CABS_OLE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ule_ps, "__builtin_mips_movf_cabs_ule_ps",
-    MIPS_BUILTIN_MOVF_CABS_ULE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_sf_ps, "__builtin_mips_movf_cabs_sf_ps",
-    MIPS_BUILTIN_MOVF_CABS_SF_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngle_ps, "__builtin_mips_movf_cabs_ngle_ps",
-    MIPS_BUILTIN_MOVF_CABS_NGLE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_seq_ps, "__builtin_mips_movf_cabs_seq_ps",
-    MIPS_BUILTIN_MOVF_CABS_SEQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngl_ps, "__builtin_mips_movf_cabs_ngl_ps",
-    MIPS_BUILTIN_MOVF_CABS_NGL_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_lt_ps, "__builtin_mips_movf_cabs_lt_ps",
-    MIPS_BUILTIN_MOVF_CABS_LT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_nge_ps, "__builtin_mips_movf_cabs_nge_ps",
-    MIPS_BUILTIN_MOVF_CABS_NGE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_le_ps, "__builtin_mips_movf_cabs_le_ps",
-    MIPS_BUILTIN_MOVF_CABS_LE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-  { CODE_FOR_mips_cabs_ngt_ps, "__builtin_mips_movf_cabs_ngt_ps",
-    MIPS_BUILTIN_MOVF_CABS_NGT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
-    MASK_MIPS3D },
-
+  DIRECT_BUILTIN (pll_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE_FLOAT),
+  DIRECT_BUILTIN (pul_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE_FLOAT),
+  DIRECT_BUILTIN (plu_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE_FLOAT),
+  DIRECT_BUILTIN (puu_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE_FLOAT),
+  DIRECT_BUILTIN (cvt_ps_s, MIPS_V2SF_FTYPE_SF_SF, MASK_PAIRED_SINGLE_FLOAT),
+  DIRECT_BUILTIN (cvt_s_pl, MIPS_SF_FTYPE_V2SF, MASK_PAIRED_SINGLE_FLOAT),
+  DIRECT_BUILTIN (cvt_s_pu, MIPS_SF_FTYPE_V2SF, MASK_PAIRED_SINGLE_FLOAT),
+  DIRECT_BUILTIN (abs_ps, MIPS_V2SF_FTYPE_V2SF, MASK_PAIRED_SINGLE_FLOAT),
+
+  DIRECT_BUILTIN (alnv_ps, MIPS_V2SF_FTYPE_V2SF_V2SF_INT,
+                 MASK_PAIRED_SINGLE_FLOAT),
+  DIRECT_BUILTIN (addr_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_MIPS3D),
+  DIRECT_BUILTIN (mulr_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_MIPS3D),
+  DIRECT_BUILTIN (cvt_pw_ps, MIPS_V2SF_FTYPE_V2SF, MASK_MIPS3D),
+  DIRECT_BUILTIN (cvt_ps_pw, MIPS_V2SF_FTYPE_V2SF, MASK_MIPS3D),
+
+  DIRECT_BUILTIN (recip1_s, MIPS_SF_FTYPE_SF, MASK_MIPS3D),
+  DIRECT_BUILTIN (recip1_d, MIPS_DF_FTYPE_DF, MASK_MIPS3D),
+  DIRECT_BUILTIN (recip1_ps, MIPS_V2SF_FTYPE_V2SF, MASK_MIPS3D),
+  DIRECT_BUILTIN (recip2_s, MIPS_SF_FTYPE_SF_SF, MASK_MIPS3D),
+  DIRECT_BUILTIN (recip2_d, MIPS_DF_FTYPE_DF_DF, MASK_MIPS3D),
+  DIRECT_BUILTIN (recip2_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_MIPS3D),
+
+  DIRECT_BUILTIN (rsqrt1_s, MIPS_SF_FTYPE_SF, MASK_MIPS3D),
+  DIRECT_BUILTIN (rsqrt1_d, MIPS_DF_FTYPE_DF, MASK_MIPS3D),
+  DIRECT_BUILTIN (rsqrt1_ps, MIPS_V2SF_FTYPE_V2SF, MASK_MIPS3D),
+  DIRECT_BUILTIN (rsqrt2_s, MIPS_SF_FTYPE_SF_SF, MASK_MIPS3D),
+  DIRECT_BUILTIN (rsqrt2_d, MIPS_DF_FTYPE_DF_DF, MASK_MIPS3D),
+  DIRECT_BUILTIN (rsqrt2_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_MIPS3D),
+
+  MIPS_FP_CONDITIONS (CMP_BUILTINS)
 };
 
+/* Builtin functions for the SB-1 processor.  */
 
-/* Expand builtin functions.  This is called from TARGET_EXPAND_BUILTIN.  */
+#define CODE_FOR_mips_sqrt_ps CODE_FOR_sqrtv2sf2
 
-rtx
-mips_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
-                    enum machine_mode mode ATTRIBUTE_UNUSED,
-                    int ignore ATTRIBUTE_UNUSED)
+static const struct builtin_description sb1_bdesc[] =
 {
-  rtx pat;
-  enum insn_code icode;
-  tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
-  tree arglist = TREE_OPERAND (exp, 1);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
-  tree arg0;
-  tree arg1;
-  tree arg2;
-  enum machine_mode tmode;
-  enum machine_mode mode0;
-  enum machine_mode mode1;
-  enum machine_mode mode2;
-  rtx op0;
-  rtx op1;
-  rtx op2;
-
-  switch (fcode)
-    {
-    /* Two Operands.  */
-    case MIPS_BUILTIN_PLL_PS:
-    case MIPS_BUILTIN_PUL_PS:
-    case MIPS_BUILTIN_PLU_PS:
-    case MIPS_BUILTIN_PUU_PS:
-    case MIPS_BUILTIN_CVT_PS_S:
-    case MIPS_BUILTIN_ADDR_PS:
-    case MIPS_BUILTIN_MULR_PS:
-    case MIPS_BUILTIN_RECIP2_S:
-    case MIPS_BUILTIN_RECIP2_D:
-    case MIPS_BUILTIN_RECIP2_PS:
-    case MIPS_BUILTIN_RSQRT2_S:
-    case MIPS_BUILTIN_RSQRT2_D:
-    case MIPS_BUILTIN_RSQRT2_PS:
-
-      icode = mips_bdesc[fcode].icode;
-      arg0 = TREE_VALUE (arglist);
-      arg1 = TREE_VALUE (TREE_CHAIN (arglist));
-      op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
-      op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
-      tmode = insn_data[icode].operand[0].mode;
-      mode0 = insn_data[icode].operand[1].mode;
-      mode1 = insn_data[icode].operand[2].mode;
-
-      if (target == 0
-         || GET_MODE (target) != tmode
-         || !(*insn_data[icode].operand[0].predicate) (target, tmode))
-       target = gen_reg_rtx (tmode);
-
-      if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
-       op0 = copy_to_mode_reg (mode0, op0);
-      if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
-       op1 = copy_to_mode_reg (mode1, op1);
-
-      pat = GEN_FCN (icode) (target, op0, op1);
-      if (!pat)
-       return 0;
-      
-      emit_insn (pat);
-      return target;
-
-    /* One Operand.  */
-    case MIPS_BUILTIN_CVT_S_PL:
-    case MIPS_BUILTIN_CVT_S_PU:
-    case MIPS_BUILTIN_ABS_PS:
-    case MIPS_BUILTIN_CVT_PW_PS:
-    case MIPS_BUILTIN_CVT_PS_PW:
-    case MIPS_BUILTIN_RECIP1_S:
-    case MIPS_BUILTIN_RECIP1_D:
-    case MIPS_BUILTIN_RECIP1_PS:
-    case MIPS_BUILTIN_RSQRT1_S:
-    case MIPS_BUILTIN_RSQRT1_D:
-    case MIPS_BUILTIN_RSQRT1_PS:
-
-      icode = mips_bdesc[fcode].icode;
-      arg0 = TREE_VALUE (arglist);
-      op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
-      tmode = insn_data[icode].operand[0].mode;
-      mode0 = insn_data[icode].operand[1].mode;
-
-      if (target == 0
-         || GET_MODE (target) != tmode
-         || !(*insn_data[icode].operand[0].predicate) (target, tmode))
-       target = gen_reg_rtx (tmode);
-
-      if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
-       op0 = copy_to_mode_reg (mode0, op0);
-      
-      pat = GEN_FCN (icode) (target, op0);
-      if (!pat)
-       return 0;
-      
-      emit_insn (pat);
-      return target;
-
-    /* Three Operands.  */
-    case MIPS_BUILTIN_ALNV_PS:
-
-      icode = mips_bdesc[fcode].icode;
-      arg0 = TREE_VALUE (arglist);
-      arg1 = TREE_VALUE (TREE_CHAIN (arglist));
-      arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
-      op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
-      op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
-      op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
-      tmode = insn_data[icode].operand[0].mode;
-      mode0 = insn_data[icode].operand[1].mode;
-      mode1 = insn_data[icode].operand[2].mode;
-      mode2 = insn_data[icode].operand[3].mode;
-
-      if (target == 0
-         || GET_MODE (target) != tmode
-         || !(*insn_data[icode].operand[0].predicate) (target, tmode))
-       target = gen_reg_rtx (tmode);
-
-      if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
-       op0 = copy_to_mode_reg (mode0, op0);
-
-      if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
-       op1 = copy_to_mode_reg (mode1, op1);
-
-      if (!(*insn_data[icode].operand[3].predicate) (op2, mode2))
-       op2 = copy_to_mode_reg (mode2, op2);
-
-      pat = GEN_FCN (icode) (target, op0, op1, op2);
-      if (!pat)
-       return 0;
-      
-      emit_insn (pat);
-      return target;
-
-    /* Paired Single Comparison.  */
-    case MIPS_BUILTIN_ANY_C_F_PS:
-    case MIPS_BUILTIN_ANY_C_UN_PS:
-    case MIPS_BUILTIN_ANY_C_EQ_PS:
-    case MIPS_BUILTIN_ANY_C_UEQ_PS:
-    case MIPS_BUILTIN_ANY_C_OLT_PS:
-    case MIPS_BUILTIN_ANY_C_ULT_PS:
-    case MIPS_BUILTIN_ANY_C_OLE_PS:
-    case MIPS_BUILTIN_ANY_C_ULE_PS:
-    case MIPS_BUILTIN_ANY_C_SF_PS:
-    case MIPS_BUILTIN_ANY_C_NGLE_PS:
-    case MIPS_BUILTIN_ANY_C_SEQ_PS:
-    case MIPS_BUILTIN_ANY_C_NGL_PS:
-    case MIPS_BUILTIN_ANY_C_LT_PS:
-    case MIPS_BUILTIN_ANY_C_NGE_PS:
-    case MIPS_BUILTIN_ANY_C_LE_PS:
-    case MIPS_BUILTIN_ANY_C_NGT_PS:
-    case MIPS_BUILTIN_ANY_CABS_F_PS:
-    case MIPS_BUILTIN_ANY_CABS_UN_PS:
-    case MIPS_BUILTIN_ANY_CABS_EQ_PS:
-    case MIPS_BUILTIN_ANY_CABS_UEQ_PS:
-    case MIPS_BUILTIN_ANY_CABS_OLT_PS:
-    case MIPS_BUILTIN_ANY_CABS_ULT_PS:
-    case MIPS_BUILTIN_ANY_CABS_OLE_PS:
-    case MIPS_BUILTIN_ANY_CABS_ULE_PS:
-    case MIPS_BUILTIN_ANY_CABS_SF_PS:
-    case MIPS_BUILTIN_ANY_CABS_NGLE_PS:
-    case MIPS_BUILTIN_ANY_CABS_SEQ_PS:
-    case MIPS_BUILTIN_ANY_CABS_NGL_PS:
-    case MIPS_BUILTIN_ANY_CABS_LT_PS:
-    case MIPS_BUILTIN_ANY_CABS_NGE_PS:
-    case MIPS_BUILTIN_ANY_CABS_LE_PS:
-    case MIPS_BUILTIN_ANY_CABS_NGT_PS:
-      return mips_expand_ps_compare_builtin (MIPS_CMP_ANY, target, 
-                                            fcode, arglist);
-
-    /* Paired Single Comparison.  */
-    case MIPS_BUILTIN_UPPER_C_F_PS:
-    case MIPS_BUILTIN_UPPER_C_UN_PS:
-    case MIPS_BUILTIN_UPPER_C_EQ_PS:
-    case MIPS_BUILTIN_UPPER_C_UEQ_PS:
-    case MIPS_BUILTIN_UPPER_C_OLT_PS:
-    case MIPS_BUILTIN_UPPER_C_ULT_PS:
-    case MIPS_BUILTIN_UPPER_C_OLE_PS:
-    case MIPS_BUILTIN_UPPER_C_ULE_PS:
-    case MIPS_BUILTIN_UPPER_C_SF_PS:
-    case MIPS_BUILTIN_UPPER_C_NGLE_PS:
-    case MIPS_BUILTIN_UPPER_C_SEQ_PS:
-    case MIPS_BUILTIN_UPPER_C_NGL_PS:
-    case MIPS_BUILTIN_UPPER_C_LT_PS:
-    case MIPS_BUILTIN_UPPER_C_NGE_PS:
-    case MIPS_BUILTIN_UPPER_C_LE_PS:
-    case MIPS_BUILTIN_UPPER_C_NGT_PS:
-    case MIPS_BUILTIN_UPPER_CABS_F_PS:
-    case MIPS_BUILTIN_UPPER_CABS_UN_PS:
-    case MIPS_BUILTIN_UPPER_CABS_EQ_PS:
-    case MIPS_BUILTIN_UPPER_CABS_UEQ_PS:
-    case MIPS_BUILTIN_UPPER_CABS_OLT_PS:
-    case MIPS_BUILTIN_UPPER_CABS_ULT_PS:
-    case MIPS_BUILTIN_UPPER_CABS_OLE_PS:
-    case MIPS_BUILTIN_UPPER_CABS_ULE_PS:
-    case MIPS_BUILTIN_UPPER_CABS_SF_PS:
-    case MIPS_BUILTIN_UPPER_CABS_NGLE_PS:
-    case MIPS_BUILTIN_UPPER_CABS_SEQ_PS:
-    case MIPS_BUILTIN_UPPER_CABS_NGL_PS:
-    case MIPS_BUILTIN_UPPER_CABS_LT_PS:
-    case MIPS_BUILTIN_UPPER_CABS_NGE_PS:
-    case MIPS_BUILTIN_UPPER_CABS_LE_PS:
-    case MIPS_BUILTIN_UPPER_CABS_NGT_PS:
-      return mips_expand_ps_compare_builtin (MIPS_CMP_UPPER, target, 
-                                            fcode, arglist);
-
-    /* Paired Single Comparison.  */
-    case MIPS_BUILTIN_LOWER_C_F_PS:
-    case MIPS_BUILTIN_LOWER_C_UN_PS:
-    case MIPS_BUILTIN_LOWER_C_EQ_PS:
-    case MIPS_BUILTIN_LOWER_C_UEQ_PS:
-    case MIPS_BUILTIN_LOWER_C_OLT_PS:
-    case MIPS_BUILTIN_LOWER_C_ULT_PS:
-    case MIPS_BUILTIN_LOWER_C_OLE_PS:
-    case MIPS_BUILTIN_LOWER_C_ULE_PS:
-    case MIPS_BUILTIN_LOWER_C_SF_PS:
-    case MIPS_BUILTIN_LOWER_C_NGLE_PS:
-    case MIPS_BUILTIN_LOWER_C_SEQ_PS:
-    case MIPS_BUILTIN_LOWER_C_NGL_PS:
-    case MIPS_BUILTIN_LOWER_C_LT_PS:
-    case MIPS_BUILTIN_LOWER_C_NGE_PS:
-    case MIPS_BUILTIN_LOWER_C_LE_PS:
-    case MIPS_BUILTIN_LOWER_C_NGT_PS:
-    case MIPS_BUILTIN_LOWER_CABS_F_PS:
-    case MIPS_BUILTIN_LOWER_CABS_UN_PS:
-    case MIPS_BUILTIN_LOWER_CABS_EQ_PS:
-    case MIPS_BUILTIN_LOWER_CABS_UEQ_PS:
-    case MIPS_BUILTIN_LOWER_CABS_OLT_PS:
-    case MIPS_BUILTIN_LOWER_CABS_ULT_PS:
-    case MIPS_BUILTIN_LOWER_CABS_OLE_PS:
-    case MIPS_BUILTIN_LOWER_CABS_ULE_PS:
-    case MIPS_BUILTIN_LOWER_CABS_SF_PS:
-    case MIPS_BUILTIN_LOWER_CABS_NGLE_PS:
-    case MIPS_BUILTIN_LOWER_CABS_SEQ_PS:
-    case MIPS_BUILTIN_LOWER_CABS_NGL_PS:
-    case MIPS_BUILTIN_LOWER_CABS_LT_PS:
-    case MIPS_BUILTIN_LOWER_CABS_NGE_PS:
-    case MIPS_BUILTIN_LOWER_CABS_LE_PS:
-    case MIPS_BUILTIN_LOWER_CABS_NGT_PS:
-      return mips_expand_ps_compare_builtin (MIPS_CMP_LOWER, target, 
-                                            fcode, arglist);
-
-    /* Paired Single Comparison.  */
-    case MIPS_BUILTIN_ALL_C_F_PS:
-    case MIPS_BUILTIN_ALL_C_UN_PS:
-    case MIPS_BUILTIN_ALL_C_EQ_PS:
-    case MIPS_BUILTIN_ALL_C_UEQ_PS:
-    case MIPS_BUILTIN_ALL_C_OLT_PS:
-    case MIPS_BUILTIN_ALL_C_ULT_PS:
-    case MIPS_BUILTIN_ALL_C_OLE_PS:
-    case MIPS_BUILTIN_ALL_C_ULE_PS:
-    case MIPS_BUILTIN_ALL_C_SF_PS:
-    case MIPS_BUILTIN_ALL_C_NGLE_PS:
-    case MIPS_BUILTIN_ALL_C_SEQ_PS:
-    case MIPS_BUILTIN_ALL_C_NGL_PS:
-    case MIPS_BUILTIN_ALL_C_LT_PS:
-    case MIPS_BUILTIN_ALL_C_NGE_PS:
-    case MIPS_BUILTIN_ALL_C_LE_PS:
-    case MIPS_BUILTIN_ALL_C_NGT_PS:
-    case MIPS_BUILTIN_ALL_CABS_F_PS:
-    case MIPS_BUILTIN_ALL_CABS_UN_PS:
-    case MIPS_BUILTIN_ALL_CABS_EQ_PS:
-    case MIPS_BUILTIN_ALL_CABS_UEQ_PS:
-    case MIPS_BUILTIN_ALL_CABS_OLT_PS:
-    case MIPS_BUILTIN_ALL_CABS_ULT_PS:
-    case MIPS_BUILTIN_ALL_CABS_OLE_PS:
-    case MIPS_BUILTIN_ALL_CABS_ULE_PS:
-    case MIPS_BUILTIN_ALL_CABS_SF_PS:
-    case MIPS_BUILTIN_ALL_CABS_NGLE_PS:
-    case MIPS_BUILTIN_ALL_CABS_SEQ_PS:
-    case MIPS_BUILTIN_ALL_CABS_NGL_PS:
-    case MIPS_BUILTIN_ALL_CABS_LT_PS:
-    case MIPS_BUILTIN_ALL_CABS_NGE_PS:
-    case MIPS_BUILTIN_ALL_CABS_LE_PS:
-    case MIPS_BUILTIN_ALL_CABS_NGT_PS:
-      return mips_expand_ps_compare_builtin (MIPS_CMP_ALL, target, 
-                                            fcode, arglist);
-
-    /* Four Single Comparison.  */
-    case MIPS_BUILTIN_ANY_C_F_4S:
-    case MIPS_BUILTIN_ANY_C_UN_4S:
-    case MIPS_BUILTIN_ANY_C_EQ_4S:
-    case MIPS_BUILTIN_ANY_C_UEQ_4S:
-    case MIPS_BUILTIN_ANY_C_OLT_4S:
-    case MIPS_BUILTIN_ANY_C_ULT_4S:
-    case MIPS_BUILTIN_ANY_C_OLE_4S:
-    case MIPS_BUILTIN_ANY_C_ULE_4S:
-    case MIPS_BUILTIN_ANY_C_SF_4S:
-    case MIPS_BUILTIN_ANY_C_NGLE_4S:
-    case MIPS_BUILTIN_ANY_C_SEQ_4S:
-    case MIPS_BUILTIN_ANY_C_NGL_4S:
-    case MIPS_BUILTIN_ANY_C_LT_4S:
-    case MIPS_BUILTIN_ANY_C_NGE_4S:
-    case MIPS_BUILTIN_ANY_C_LE_4S:
-    case MIPS_BUILTIN_ANY_C_NGT_4S:
-    case MIPS_BUILTIN_ANY_CABS_F_4S:
-    case MIPS_BUILTIN_ANY_CABS_UN_4S:
-    case MIPS_BUILTIN_ANY_CABS_EQ_4S:
-    case MIPS_BUILTIN_ANY_CABS_UEQ_4S:
-    case MIPS_BUILTIN_ANY_CABS_OLT_4S:
-    case MIPS_BUILTIN_ANY_CABS_ULT_4S:
-    case MIPS_BUILTIN_ANY_CABS_OLE_4S:
-    case MIPS_BUILTIN_ANY_CABS_ULE_4S:
-    case MIPS_BUILTIN_ANY_CABS_SF_4S:
-    case MIPS_BUILTIN_ANY_CABS_NGLE_4S:
-    case MIPS_BUILTIN_ANY_CABS_SEQ_4S:
-    case MIPS_BUILTIN_ANY_CABS_NGL_4S:
-    case MIPS_BUILTIN_ANY_CABS_LT_4S:
-    case MIPS_BUILTIN_ANY_CABS_NGE_4S:
-    case MIPS_BUILTIN_ANY_CABS_LE_4S:
-    case MIPS_BUILTIN_ANY_CABS_NGT_4S:
-      return mips_expand_4s_compare_builtin (MIPS_CMP_ANY, target, 
-                                            fcode, arglist);
-
-    /* Four Single Comparison.  */
-    case MIPS_BUILTIN_ALL_C_F_4S:
-    case MIPS_BUILTIN_ALL_C_UN_4S:
-    case MIPS_BUILTIN_ALL_C_EQ_4S:
-    case MIPS_BUILTIN_ALL_C_UEQ_4S:
-    case MIPS_BUILTIN_ALL_C_OLT_4S:
-    case MIPS_BUILTIN_ALL_C_ULT_4S:
-    case MIPS_BUILTIN_ALL_C_OLE_4S:
-    case MIPS_BUILTIN_ALL_C_ULE_4S:
-    case MIPS_BUILTIN_ALL_C_SF_4S:
-    case MIPS_BUILTIN_ALL_C_NGLE_4S:
-    case MIPS_BUILTIN_ALL_C_SEQ_4S:
-    case MIPS_BUILTIN_ALL_C_NGL_4S:
-    case MIPS_BUILTIN_ALL_C_LT_4S:
-    case MIPS_BUILTIN_ALL_C_NGE_4S:
-    case MIPS_BUILTIN_ALL_C_LE_4S:
-    case MIPS_BUILTIN_ALL_C_NGT_4S:
-    case MIPS_BUILTIN_ALL_CABS_F_4S:
-    case MIPS_BUILTIN_ALL_CABS_UN_4S:
-    case MIPS_BUILTIN_ALL_CABS_EQ_4S:
-    case MIPS_BUILTIN_ALL_CABS_UEQ_4S:
-    case MIPS_BUILTIN_ALL_CABS_OLT_4S:
-    case MIPS_BUILTIN_ALL_CABS_ULT_4S:
-    case MIPS_BUILTIN_ALL_CABS_OLE_4S:
-    case MIPS_BUILTIN_ALL_CABS_ULE_4S:
-    case MIPS_BUILTIN_ALL_CABS_SF_4S:
-    case MIPS_BUILTIN_ALL_CABS_NGLE_4S:
-    case MIPS_BUILTIN_ALL_CABS_SEQ_4S:
-    case MIPS_BUILTIN_ALL_CABS_NGL_4S:
-    case MIPS_BUILTIN_ALL_CABS_LT_4S:
-    case MIPS_BUILTIN_ALL_CABS_NGE_4S:
-    case MIPS_BUILTIN_ALL_CABS_LE_4S:
-    case MIPS_BUILTIN_ALL_CABS_NGT_4S:
-      return mips_expand_4s_compare_builtin (MIPS_CMP_ALL, target, 
-                                            fcode, arglist);
-
-    /* Single/Double Compare Absolute.  */
-    case MIPS_BUILTIN_CABS_F_S:
-    case MIPS_BUILTIN_CABS_UN_S:
-    case MIPS_BUILTIN_CABS_EQ_S:
-    case MIPS_BUILTIN_CABS_UEQ_S:
-    case MIPS_BUILTIN_CABS_OLT_S:
-    case MIPS_BUILTIN_CABS_ULT_S:
-    case MIPS_BUILTIN_CABS_OLE_S:
-    case MIPS_BUILTIN_CABS_ULE_S:
-    case MIPS_BUILTIN_CABS_SF_S:
-    case MIPS_BUILTIN_CABS_NGLE_S:
-    case MIPS_BUILTIN_CABS_SEQ_S:
-    case MIPS_BUILTIN_CABS_NGL_S:
-    case MIPS_BUILTIN_CABS_LT_S:
-    case MIPS_BUILTIN_CABS_NGE_S:
-    case MIPS_BUILTIN_CABS_LE_S:
-    case MIPS_BUILTIN_CABS_NGT_S:
-    case MIPS_BUILTIN_CABS_F_D:
-    case MIPS_BUILTIN_CABS_UN_D:
-    case MIPS_BUILTIN_CABS_EQ_D:
-    case MIPS_BUILTIN_CABS_UEQ_D:
-    case MIPS_BUILTIN_CABS_OLT_D:
-    case MIPS_BUILTIN_CABS_ULT_D:
-    case MIPS_BUILTIN_CABS_OLE_D:
-    case MIPS_BUILTIN_CABS_ULE_D:
-    case MIPS_BUILTIN_CABS_SF_D:
-    case MIPS_BUILTIN_CABS_NGLE_D:
-    case MIPS_BUILTIN_CABS_SEQ_D:
-    case MIPS_BUILTIN_CABS_NGL_D:
-    case MIPS_BUILTIN_CABS_LT_D:
-    case MIPS_BUILTIN_CABS_NGE_D:
-    case MIPS_BUILTIN_CABS_LE_D:
-    case MIPS_BUILTIN_CABS_NGT_D:
-      return mips_expand_compare_builtin (target, fcode, arglist);
-
-    /* Conditional Move on True.  */
-    case MIPS_BUILTIN_MOVT_C_F_PS:
-    case MIPS_BUILTIN_MOVT_C_UN_PS:
-    case MIPS_BUILTIN_MOVT_C_EQ_PS:
-    case MIPS_BUILTIN_MOVT_C_UEQ_PS:
-    case MIPS_BUILTIN_MOVT_C_OLT_PS:
-    case MIPS_BUILTIN_MOVT_C_ULT_PS:
-    case MIPS_BUILTIN_MOVT_C_OLE_PS:
-    case MIPS_BUILTIN_MOVT_C_ULE_PS:
-    case MIPS_BUILTIN_MOVT_C_SF_PS:
-    case MIPS_BUILTIN_MOVT_C_NGLE_PS:
-    case MIPS_BUILTIN_MOVT_C_SEQ_PS:
-    case MIPS_BUILTIN_MOVT_C_NGL_PS:
-    case MIPS_BUILTIN_MOVT_C_LT_PS:
-    case MIPS_BUILTIN_MOVT_C_NGE_PS:
-    case MIPS_BUILTIN_MOVT_C_LE_PS:
-    case MIPS_BUILTIN_MOVT_C_NGT_PS:
-    case MIPS_BUILTIN_MOVT_CABS_F_PS:
-    case MIPS_BUILTIN_MOVT_CABS_UN_PS:
-    case MIPS_BUILTIN_MOVT_CABS_EQ_PS:
-    case MIPS_BUILTIN_MOVT_CABS_UEQ_PS:
-    case MIPS_BUILTIN_MOVT_CABS_OLT_PS:
-    case MIPS_BUILTIN_MOVT_CABS_ULT_PS:
-    case MIPS_BUILTIN_MOVT_CABS_OLE_PS:
-    case MIPS_BUILTIN_MOVT_CABS_ULE_PS:
-    case MIPS_BUILTIN_MOVT_CABS_SF_PS:
-    case MIPS_BUILTIN_MOVT_CABS_NGLE_PS:
-    case MIPS_BUILTIN_MOVT_CABS_SEQ_PS:
-    case MIPS_BUILTIN_MOVT_CABS_NGL_PS:
-    case MIPS_BUILTIN_MOVT_CABS_LT_PS:
-    case MIPS_BUILTIN_MOVT_CABS_NGE_PS:
-    case MIPS_BUILTIN_MOVT_CABS_LE_PS:
-    case MIPS_BUILTIN_MOVT_CABS_NGT_PS:
-      return mips_expand_ps_cond_move_builtin (MIPS_CMP_MOVT, target, 
-                                              fcode, arglist);
-
-    /* Conditional Move on False.  */
-    case MIPS_BUILTIN_MOVF_C_F_PS:
-    case MIPS_BUILTIN_MOVF_C_UN_PS:
-    case MIPS_BUILTIN_MOVF_C_EQ_PS:
-    case MIPS_BUILTIN_MOVF_C_UEQ_PS:
-    case MIPS_BUILTIN_MOVF_C_OLT_PS:
-    case MIPS_BUILTIN_MOVF_C_ULT_PS:
-    case MIPS_BUILTIN_MOVF_C_OLE_PS:
-    case MIPS_BUILTIN_MOVF_C_ULE_PS:
-    case MIPS_BUILTIN_MOVF_C_SF_PS:
-    case MIPS_BUILTIN_MOVF_C_NGLE_PS:
-    case MIPS_BUILTIN_MOVF_C_SEQ_PS:
-    case MIPS_BUILTIN_MOVF_C_NGL_PS:
-    case MIPS_BUILTIN_MOVF_C_LT_PS:
-    case MIPS_BUILTIN_MOVF_C_NGE_PS:
-    case MIPS_BUILTIN_MOVF_C_LE_PS:
-    case MIPS_BUILTIN_MOVF_C_NGT_PS:
-    case MIPS_BUILTIN_MOVF_CABS_F_PS:
-    case MIPS_BUILTIN_MOVF_CABS_UN_PS:
-    case MIPS_BUILTIN_MOVF_CABS_EQ_PS:
-    case MIPS_BUILTIN_MOVF_CABS_UEQ_PS:
-    case MIPS_BUILTIN_MOVF_CABS_OLT_PS:
-    case MIPS_BUILTIN_MOVF_CABS_ULT_PS:
-    case MIPS_BUILTIN_MOVF_CABS_OLE_PS:
-    case MIPS_BUILTIN_MOVF_CABS_ULE_PS:
-    case MIPS_BUILTIN_MOVF_CABS_SF_PS:
-    case MIPS_BUILTIN_MOVF_CABS_NGLE_PS:
-    case MIPS_BUILTIN_MOVF_CABS_SEQ_PS:
-    case MIPS_BUILTIN_MOVF_CABS_NGL_PS:
-    case MIPS_BUILTIN_MOVF_CABS_LT_PS:
-    case MIPS_BUILTIN_MOVF_CABS_NGE_PS:
-    case MIPS_BUILTIN_MOVF_CABS_LE_PS:
-    case MIPS_BUILTIN_MOVF_CABS_NGT_PS:
-      return mips_expand_ps_cond_move_builtin (MIPS_CMP_MOVF, target, 
-                                              fcode, arglist);
-
-    default:
-      break;
-    }
+  DIRECT_BUILTIN (sqrt_ps, MIPS_V2SF_FTYPE_V2SF, MASK_PAIRED_SINGLE_FLOAT)
+};
 
-  return 0;
-}
+/* Builtin functions for DSP ASE.  */
+
+#define CODE_FOR_mips_addq_ph CODE_FOR_addv2hi3
+#define CODE_FOR_mips_addu_qb CODE_FOR_addv4qi3
+#define CODE_FOR_mips_subq_ph CODE_FOR_subv2hi3
+#define CODE_FOR_mips_subu_qb CODE_FOR_subv4qi3
+
+/* Define a MIPS_BUILTIN_DIRECT_NO_TARGET function for instruction
+   CODE_FOR_mips_<INSN>.  FUNCTION_TYPE and TARGET_FLAGS are
+   builtin_description fields.  */
+#define DIRECT_NO_TARGET_BUILTIN(INSN, FUNCTION_TYPE, TARGET_FLAGS)    \
+  { CODE_FOR_mips_ ## INSN, 0, "__builtin_mips_" #INSN,                        \
+    MIPS_BUILTIN_DIRECT_NO_TARGET, FUNCTION_TYPE, TARGET_FLAGS }
+
+/* Define __builtin_mips_bposge<VALUE>.  <VALUE> is 32 for the MIPS32 DSP
+   branch instruction.  TARGET_FLAGS is a builtin_description field.  */
+#define BPOSGE_BUILTIN(VALUE, TARGET_FLAGS)                            \
+  { CODE_FOR_mips_bposge, 0, "__builtin_mips_bposge" #VALUE,           \
+    MIPS_BUILTIN_BPOSGE ## VALUE, MIPS_SI_FTYPE_VOID, TARGET_FLAGS }
+
+static const struct builtin_description dsp_bdesc[] =
+{
+  DIRECT_BUILTIN (addq_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (addq_s_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (addq_s_w, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
+  DIRECT_BUILTIN (addu_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (addu_s_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (subq_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (subq_s_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (subq_s_w, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
+  DIRECT_BUILTIN (subu_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (subu_s_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (addsc, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
+  DIRECT_BUILTIN (addwc, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
+  DIRECT_BUILTIN (modsub, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
+  DIRECT_BUILTIN (raddu_w_qb, MIPS_SI_FTYPE_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (absq_s_ph, MIPS_V2HI_FTYPE_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (absq_s_w, MIPS_SI_FTYPE_SI, MASK_DSP),
+  DIRECT_BUILTIN (precrq_qb_ph, MIPS_V4QI_FTYPE_V2HI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (precrq_ph_w, MIPS_V2HI_FTYPE_SI_SI, MASK_DSP),
+  DIRECT_BUILTIN (precrq_rs_ph_w, MIPS_V2HI_FTYPE_SI_SI, MASK_DSP),
+  DIRECT_BUILTIN (precrqu_s_qb_ph, MIPS_V4QI_FTYPE_V2HI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (preceq_w_phl, MIPS_SI_FTYPE_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (preceq_w_phr, MIPS_SI_FTYPE_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (precequ_ph_qbl, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (precequ_ph_qbr, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (precequ_ph_qbla, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (precequ_ph_qbra, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (preceu_ph_qbl, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (preceu_ph_qbr, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (preceu_ph_qbla, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (preceu_ph_qbra, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (shll_qb, MIPS_V4QI_FTYPE_V4QI_SI, MASK_DSP),
+  DIRECT_BUILTIN (shll_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP),
+  DIRECT_BUILTIN (shll_s_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP),
+  DIRECT_BUILTIN (shll_s_w, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
+  DIRECT_BUILTIN (shrl_qb, MIPS_V4QI_FTYPE_V4QI_SI, MASK_DSP),
+  DIRECT_BUILTIN (shra_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP),
+  DIRECT_BUILTIN (shra_r_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP),
+  DIRECT_BUILTIN (shra_r_w, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
+  DIRECT_BUILTIN (muleu_s_ph_qbl, MIPS_V2HI_FTYPE_V4QI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (muleu_s_ph_qbr, MIPS_V2HI_FTYPE_V4QI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (mulq_rs_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (muleq_s_w_phl, MIPS_SI_FTYPE_V2HI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (muleq_s_w_phr, MIPS_SI_FTYPE_V2HI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (dpau_h_qbl, MIPS_DI_FTYPE_DI_V4QI_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (dpau_h_qbr, MIPS_DI_FTYPE_DI_V4QI_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (dpsu_h_qbl, MIPS_DI_FTYPE_DI_V4QI_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (dpsu_h_qbr, MIPS_DI_FTYPE_DI_V4QI_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (dpaq_s_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (dpsq_s_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (mulsaq_s_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (dpaq_sa_l_w, MIPS_DI_FTYPE_DI_SI_SI, MASK_DSP),
+  DIRECT_BUILTIN (dpsq_sa_l_w, MIPS_DI_FTYPE_DI_SI_SI, MASK_DSP),
+  DIRECT_BUILTIN (maq_s_w_phl, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (maq_s_w_phr, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (maq_sa_w_phl, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (maq_sa_w_phr, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (bitrev, MIPS_SI_FTYPE_SI, MASK_DSP),
+  DIRECT_BUILTIN (insv, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
+  DIRECT_BUILTIN (repl_qb, MIPS_V4QI_FTYPE_SI, MASK_DSP),
+  DIRECT_BUILTIN (repl_ph, MIPS_V2HI_FTYPE_SI, MASK_DSP),
+  DIRECT_NO_TARGET_BUILTIN (cmpu_eq_qb, MIPS_VOID_FTYPE_V4QI_V4QI, MASK_DSP),
+  DIRECT_NO_TARGET_BUILTIN (cmpu_lt_qb, MIPS_VOID_FTYPE_V4QI_V4QI, MASK_DSP),
+  DIRECT_NO_TARGET_BUILTIN (cmpu_le_qb, MIPS_VOID_FTYPE_V4QI_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (cmpgu_eq_qb, MIPS_SI_FTYPE_V4QI_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (cmpgu_lt_qb, MIPS_SI_FTYPE_V4QI_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (cmpgu_le_qb, MIPS_SI_FTYPE_V4QI_V4QI, MASK_DSP),
+  DIRECT_NO_TARGET_BUILTIN (cmp_eq_ph, MIPS_VOID_FTYPE_V2HI_V2HI, MASK_DSP),
+  DIRECT_NO_TARGET_BUILTIN (cmp_lt_ph, MIPS_VOID_FTYPE_V2HI_V2HI, MASK_DSP),
+  DIRECT_NO_TARGET_BUILTIN (cmp_le_ph, MIPS_VOID_FTYPE_V2HI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (pick_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, MASK_DSP),
+  DIRECT_BUILTIN (pick_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (packrl_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
+  DIRECT_BUILTIN (extr_w, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
+  DIRECT_BUILTIN (extr_r_w, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
+  DIRECT_BUILTIN (extr_rs_w, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
+  DIRECT_BUILTIN (extr_s_h, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
+  DIRECT_BUILTIN (extp, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
+  DIRECT_BUILTIN (extpdp, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
+  DIRECT_BUILTIN (shilo, MIPS_DI_FTYPE_DI_SI, MASK_DSP),
+  DIRECT_BUILTIN (mthlip, MIPS_DI_FTYPE_DI_SI, MASK_DSP),
+  DIRECT_NO_TARGET_BUILTIN (wrdsp, MIPS_VOID_FTYPE_SI_SI, MASK_DSP),
+  DIRECT_BUILTIN (rddsp, MIPS_SI_FTYPE_SI, MASK_DSP),
+  DIRECT_BUILTIN (lbux, MIPS_SI_FTYPE_PTR_SI, MASK_DSP),
+  DIRECT_BUILTIN (lhx, MIPS_SI_FTYPE_PTR_SI, MASK_DSP),
+  DIRECT_BUILTIN (lwx, MIPS_SI_FTYPE_PTR_SI, MASK_DSP),
+  BPOSGE_BUILTIN (32, MASK_DSP)
+};
 
-/* Init builtin functions.  This is called from TARGET_INIT_BUILTIN.  */
+/* This helps provide a mapping from builtin function codes to bdesc
+   arrays.  */
 
-void
-mips_init_builtins (void)
+struct bdesc_map
 {
-  const struct builtin_description *d;
-  size_t i;
-  tree v2sf_ftype_v2sf_v2sf;
-  tree v2sf_ftype_sf_sf;
-  tree sf_ftype_v2sf;
-  tree v2sf_ftype_v2sf;
-  tree int_ftype_v2sf_v2sf;
-  tree int_ftype_v2sf_v2sf_v2sf_v2sf;
-  tree v2sf_ftype_v2sf_v2sf_int;
-  tree int_ftype_sf_sf;
-  tree int_ftype_df_df;
-  tree sf_ftype_sf;
-  tree df_ftype_df;
-  tree sf_ftype_sf_sf;
-  tree df_ftype_df_df;
-  tree v2sf_ftype_v2sf_v2sf_v2sf_v2sf;
-  tree V2SF_type_node = build_vector_type_for_mode (float_type_node, V2SFmode);
-
-  /* We have only builtins for -mpaired-single and -mips3d.  */
-  if (!TARGET_PAIRED_SINGLE_FLOAT)
-    return;
+  /* The builtin function table that this entry describes.  */
+  const struct builtin_description *bdesc;
 
-  int_ftype_sf_sf
-    = build_function_type_list (integer_type_node, 
-                               float_type_node, float_type_node, 
-                               NULL_TREE);
+  /* The number of entries in the builtin function table.  */
+  unsigned int size;
 
-  int_ftype_df_df 
-    = build_function_type_list (integer_type_node, 
-                               double_type_node, double_type_node, 
-                               NULL_TREE);
+  /* The target processor that supports these builtin functions.
+     PROCESSOR_MAX means we enable them for all processors.  */
+  enum processor_type proc;
+};
 
-  v2sf_ftype_v2sf_v2sf 
-    = build_function_type_list (V2SF_type_node, 
-                               V2SF_type_node, V2SF_type_node, NULL_TREE);
+static const struct bdesc_map bdesc_arrays[] =
+{
+  { mips_bdesc, ARRAY_SIZE (mips_bdesc), PROCESSOR_MAX },
+  { sb1_bdesc, ARRAY_SIZE (sb1_bdesc), PROCESSOR_SB1 },
+  { dsp_bdesc, ARRAY_SIZE (dsp_bdesc), PROCESSOR_MAX }
+};
 
-  v2sf_ftype_sf_sf 
-    = build_function_type_list (V2SF_type_node, 
-                               float_type_node, float_type_node, 
-                               NULL_TREE);
+/* Take the head of argument list *ARGLIST and convert it into a form
+   suitable for input operand OP of instruction ICODE.  Return the value
+   and point *ARGLIST at the next element of the list.  */
 
-  sf_ftype_v2sf 
-    = build_function_type_list (float_type_node, V2SF_type_node, NULL_TREE);
+static rtx
+mips_prepare_builtin_arg (enum insn_code icode,
+                         unsigned int op, tree *arglist)
+{
+  rtx value;
+  enum machine_mode mode;
 
-  v2sf_ftype_v2sf 
-    = build_function_type_list (V2SF_type_node, V2SF_type_node, NULL_TREE);
+  value = expand_expr (TREE_VALUE (*arglist), NULL_RTX, VOIDmode, 0);
+  mode = insn_data[icode].operand[op].mode;
+  if (!insn_data[icode].operand[op].predicate (value, mode))
+    {
+      value = copy_to_mode_reg (mode, value);
+      /* Check the predicate again.  */
+      if (!insn_data[icode].operand[op].predicate (value, mode))
+       {
+         error ("invalid argument to builtin function");
+         return const0_rtx;
+       }
+    }
 
-  int_ftype_v2sf_v2sf 
-    = build_function_type_list (integer_type_node,
-                               V2SF_type_node, V2SF_type_node, NULL_TREE);
+  *arglist = TREE_CHAIN (*arglist);
+  return value;
+}
 
-  int_ftype_v2sf_v2sf_v2sf_v2sf
-    = build_function_type_list (integer_type_node,
-                               V2SF_type_node, V2SF_type_node,
-                               V2SF_type_node, V2SF_type_node, NULL_TREE);
+/* Return an rtx suitable for output operand OP of instruction ICODE.
+   If TARGET is non-null, try to use it where possible.  */
 
-  v2sf_ftype_v2sf_v2sf_v2sf_v2sf
-    = build_function_type_list (V2SF_type_node,
-                               V2SF_type_node, V2SF_type_node, 
-                               V2SF_type_node, V2SF_type_node, NULL_TREE);
+static rtx
+mips_prepare_builtin_target (enum insn_code icode, unsigned int op, rtx target)
+{
+  enum machine_mode mode;
 
-  v2sf_ftype_v2sf_v2sf_int
-    = build_function_type_list (V2SF_type_node, 
-                               V2SF_type_node, V2SF_type_node, 
-                               integer_type_node, NULL_TREE);
+  mode = insn_data[icode].operand[op].mode;
+  if (target == 0 || !insn_data[icode].operand[op].predicate (target, mode))
+    target = gen_reg_rtx (mode);
 
-  sf_ftype_sf
-    = build_function_type_list (float_type_node, 
-                               float_type_node, NULL_TREE);
+  return target;
+}
 
-  df_ftype_df
-    = build_function_type_list (double_type_node, 
-                               double_type_node, NULL_TREE);
+/* Expand builtin functions.  This is called from TARGET_EXPAND_BUILTIN.  */
 
-  sf_ftype_sf_sf
-    = build_function_type_list (float_type_node, 
-                               float_type_node, float_type_node, 
-                               NULL_TREE);
+rtx
+mips_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
+                    enum machine_mode mode ATTRIBUTE_UNUSED,
+                    int ignore ATTRIBUTE_UNUSED)
+{
+  enum insn_code icode;
+  enum mips_builtin_type type;
+  tree fndecl, arglist;
+  unsigned int fcode;
+  const struct builtin_description *bdesc;
+  const struct bdesc_map *m;
 
-  df_ftype_df_df
-    = build_function_type_list (double_type_node, 
-                               double_type_node, double_type_node, 
-                               NULL_TREE);
+  fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+  arglist = TREE_OPERAND (exp, 1);
+  fcode = DECL_FUNCTION_CODE (fndecl);
 
-  for (i = 0, d = mips_bdesc; i < ARRAY_SIZE (mips_bdesc); i++, d++)
+  bdesc = NULL;
+  for (m = bdesc_arrays; m < &bdesc_arrays[ARRAY_SIZE (bdesc_arrays)]; m++)
     {
-      if ((d->target_flags & MASK_PAIRED_SINGLE)
-         && !TARGET_PAIRED_SINGLE_FLOAT)
-       continue;
-
-      if ((d->target_flags & MASK_MIPS3D) 
-         && !TARGET_MIPS3D)
-       continue;
-
-      switch (d->ftype)
+      if (fcode < m->size)
        {
-       case MIPS_V2SF_FTYPE_V2SF_V2SF:
-         lang_hooks.builtin_function (d->name, v2sf_ftype_v2sf_v2sf,
-                                      d->code, BUILT_IN_MD, NULL, NULL_TREE);
+         bdesc = m->bdesc;
+         icode = bdesc[fcode].icode;
+         type = bdesc[fcode].builtin_type;
          break;
+       }
+      fcode -= m->size;
+    }
+  if (bdesc == NULL)
+    return 0;
 
-       case MIPS_V2SF_FTYPE_SF_SF:
-         lang_hooks.builtin_function (d->name, v2sf_ftype_sf_sf,
-                                      d->code, BUILT_IN_MD, NULL, NULL_TREE);
-         break;
+  switch (type)
+    {
+    case MIPS_BUILTIN_DIRECT:
+      return mips_expand_builtin_direct (icode, target, arglist, true);
 
-       case MIPS_SF_FTYPE_V2SF:
-         lang_hooks.builtin_function (d->name, sf_ftype_v2sf,
-                                      d->code, BUILT_IN_MD, NULL, NULL_TREE);
-         break;
+    case MIPS_BUILTIN_DIRECT_NO_TARGET:
+      return mips_expand_builtin_direct (icode, target, arglist, false);
 
-       case MIPS_V2SF_FTYPE_V2SF:
-         lang_hooks.builtin_function (d->name, v2sf_ftype_v2sf,
-                                      d->code, BUILT_IN_MD, NULL, NULL_TREE);
-         break;
+    case MIPS_BUILTIN_MOVT:
+    case MIPS_BUILTIN_MOVF:
+      return mips_expand_builtin_movtf (type, icode, bdesc[fcode].cond,
+                                       target, arglist);
 
-       case MIPS_INT_FTYPE_V2SF_V2SF:
-         lang_hooks.builtin_function (d->name, int_ftype_v2sf_v2sf,
-                                      d->code, BUILT_IN_MD, NULL, NULL_TREE);
-         break;
+    case MIPS_BUILTIN_CMP_ANY:
+    case MIPS_BUILTIN_CMP_ALL:
+    case MIPS_BUILTIN_CMP_UPPER:
+    case MIPS_BUILTIN_CMP_LOWER:
+    case MIPS_BUILTIN_CMP_SINGLE:
+      return mips_expand_builtin_compare (type, icode, bdesc[fcode].cond,
+                                         target, arglist);
 
-       case MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF:
-         lang_hooks.builtin_function (d->name, int_ftype_v2sf_v2sf_v2sf_v2sf,
-                                      d->code, BUILT_IN_MD, NULL, NULL_TREE);
-         break;
+    case MIPS_BUILTIN_BPOSGE32:
+      return mips_expand_builtin_bposge (type, target);
 
-       case MIPS_V2SF_FTYPE_V2SF_V2SF_INT:
-         lang_hooks.builtin_function (d->name, v2sf_ftype_v2sf_v2sf_int,
-                                      d->code, BUILT_IN_MD, NULL, NULL_TREE);
-         break;
+    default:
+      return 0;
+    }
+}
 
-       case MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF:
-         lang_hooks.builtin_function (d->name, v2sf_ftype_v2sf_v2sf_v2sf_v2sf,
-                                      d->code, BUILT_IN_MD, NULL, NULL_TREE);
-         break;
+/* Init builtin functions.  This is called from TARGET_INIT_BUILTIN.  */
 
-       case MIPS_SF_FTYPE_SF:
-         lang_hooks.builtin_function (d->name, sf_ftype_sf,
-                                      d->code, BUILT_IN_MD, NULL, NULL_TREE);
-         break;
+void
+mips_init_builtins (void)
+{
+  const struct builtin_description *d;
+  const struct bdesc_map *m;
+  tree types[(int) MIPS_MAX_FTYPE_MAX];
+  tree V2SF_type_node;
+  tree V2HI_type_node;
+  tree V4QI_type_node;
+  unsigned int offset;
+
+  /* We have only builtins for -mpaired-single, -mips3d and -mdsp.  */
+  if (!TARGET_PAIRED_SINGLE_FLOAT && !TARGET_DSP)
+    return;
 
-       case MIPS_DF_FTYPE_DF:
-         lang_hooks.builtin_function (d->name, df_ftype_df,
-                                      d->code, BUILT_IN_MD, NULL, NULL_TREE);
-         break;
+  if (TARGET_PAIRED_SINGLE_FLOAT)
+    {
+      V2SF_type_node = build_vector_type_for_mode (float_type_node, V2SFmode);
 
-       case MIPS_INT_FTYPE_SF_SF:
-         lang_hooks.builtin_function (d->name, int_ftype_sf_sf,
-                                      d->code, BUILT_IN_MD, NULL, NULL_TREE);
-         break;
+      types[MIPS_V2SF_FTYPE_V2SF]
+       = build_function_type_list (V2SF_type_node, V2SF_type_node, NULL_TREE);
 
-       case MIPS_INT_FTYPE_DF_DF:
-         lang_hooks.builtin_function (d->name, int_ftype_df_df,
-                                      d->code, BUILT_IN_MD, NULL, NULL_TREE);
-         break;
+      types[MIPS_V2SF_FTYPE_V2SF_V2SF]
+       = build_function_type_list (V2SF_type_node,
+                                   V2SF_type_node, V2SF_type_node, NULL_TREE);
 
-       case MIPS_SF_FTYPE_SF_SF:
-         lang_hooks.builtin_function (d->name, sf_ftype_sf_sf,
-                                      d->code, BUILT_IN_MD, NULL, NULL_TREE);
-         break;
+      types[MIPS_V2SF_FTYPE_V2SF_V2SF_INT]
+       = build_function_type_list (V2SF_type_node,
+                                   V2SF_type_node, V2SF_type_node,
+                                   integer_type_node, NULL_TREE);
 
-       case MIPS_DF_FTYPE_DF_DF:
-         lang_hooks.builtin_function (d->name, df_ftype_df_df,
-                                      d->code, BUILT_IN_MD, NULL, NULL_TREE);
-         break;
+      types[MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF]
+       = build_function_type_list (V2SF_type_node,
+                                   V2SF_type_node, V2SF_type_node,
+                                   V2SF_type_node, V2SF_type_node, NULL_TREE);
 
-       default:
-         break;
-       }
-    }
-}
+      types[MIPS_V2SF_FTYPE_SF_SF]
+       = build_function_type_list (V2SF_type_node,
+                                   float_type_node, float_type_node, NULL_TREE);
 
-/* This performs a paired single compare, and then a conditional move based
-   on the result of that compare.  CMP_CHOICE is the kind of comparison we
-   want.  TARGET is a suggestion of where to put the result.  FCODE is the
-   function code.  ARGLIST is the list of arguments.  The return value is
-   the result of the conditional move.  */
+      types[MIPS_INT_FTYPE_V2SF_V2SF]
+       = build_function_type_list (integer_type_node,
+                                   V2SF_type_node, V2SF_type_node, NULL_TREE);
 
-static rtx
-mips_expand_ps_cond_move_builtin (enum mips_cmp_choice cmp_choice,
-                                 rtx target, unsigned int fcode,
-                                 tree arglist)
-{
-  rtx pat;
-  enum insn_code icode;
-  tree arg0;
-  tree arg1;
-  tree arg2;
-  tree arg3;
-  rtx op0;
-  rtx op1;
-  rtx op2;
-  rtx op3;
-  enum machine_mode tmode;
-  enum machine_mode mode0;
-  enum machine_mode mode1;
-  rtx temp_target;
-  rtx src1;
-  rtx src2;
-  enum rtx_code test_code;
-  int compare_value;
-
-  arg0 = TREE_VALUE (arglist);
-  arg1 = TREE_VALUE (TREE_CHAIN (arglist));
-  arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
-  arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
-  op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
-  op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
-  op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
-  op3 = expand_expr (arg3, NULL_RTX, VOIDmode, 0);
-
-  icode = mips_bdesc[fcode].icode;
-  tmode = insn_data[icode].operand[0].mode;
-  mode0 = insn_data[icode].operand[1].mode;
-  mode1 = insn_data[icode].operand[2].mode;
-
-  if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
-    op0 = copy_to_mode_reg (mode0, op0);
-
-  if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
-    op1 = copy_to_mode_reg (mode1, op1);
-
-  /* temp_target is the result of the comparison.  */
-  temp_target = gen_reg_rtx (tmode);
-
-  pat = GEN_FCN (icode) (temp_target, op0, op1);
-  if (!pat)
-    return 0;
+      types[MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF]
+       = build_function_type_list (integer_type_node,
+                                   V2SF_type_node, V2SF_type_node,
+                                   V2SF_type_node, V2SF_type_node, NULL_TREE);
 
-  emit_insn (pat);
+      types[MIPS_INT_FTYPE_SF_SF]
+       = build_function_type_list (integer_type_node,
+                                   float_type_node, float_type_node, NULL_TREE);
 
-  icode = CODE_FOR_mips_cond_move_tf_ps;
-  tmode = insn_data[icode].operand[0].mode;
+      types[MIPS_INT_FTYPE_DF_DF]
+       = build_function_type_list (integer_type_node,
+                                   double_type_node, double_type_node, NULL_TREE);
 
-  if (target == 0
-      || GET_MODE (target) != tmode
-      || !(*insn_data[icode].operand[0].predicate) (target, tmode))
-    target = gen_reg_rtx (tmode);
+      types[MIPS_SF_FTYPE_V2SF]
+       = build_function_type_list (float_type_node, V2SF_type_node, NULL_TREE);
+
+      types[MIPS_SF_FTYPE_SF]
+       = build_function_type_list (float_type_node,
+                                   float_type_node, NULL_TREE);
+
+      types[MIPS_SF_FTYPE_SF_SF]
+       = build_function_type_list (float_type_node,
+                                   float_type_node, float_type_node, NULL_TREE);
+
+      types[MIPS_DF_FTYPE_DF]
+       = build_function_type_list (double_type_node,
+                                   double_type_node, NULL_TREE);
+
+      types[MIPS_DF_FTYPE_DF_DF]
+       = build_function_type_list (double_type_node,
+                                   double_type_node, double_type_node, NULL_TREE);
+    }
+
+  if (TARGET_DSP)
+    {
+      V2HI_type_node = build_vector_type_for_mode (intHI_type_node, V2HImode);
+      V4QI_type_node = build_vector_type_for_mode (intQI_type_node, V4QImode);
+
+      types[MIPS_V2HI_FTYPE_V2HI_V2HI]
+       = build_function_type_list (V2HI_type_node,
+                                   V2HI_type_node, V2HI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_SI_FTYPE_SI_SI]
+       = build_function_type_list (intSI_type_node,
+                                   intSI_type_node, intSI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_V4QI_FTYPE_V4QI_V4QI]
+       = build_function_type_list (V4QI_type_node,
+                                   V4QI_type_node, V4QI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_SI_FTYPE_V4QI]
+       = build_function_type_list (intSI_type_node,
+                                   V4QI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_V2HI_FTYPE_V2HI]
+       = build_function_type_list (V2HI_type_node,
+                                   V2HI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_SI_FTYPE_SI]
+       = build_function_type_list (intSI_type_node,
+                                   intSI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_V4QI_FTYPE_V2HI_V2HI]
+       = build_function_type_list (V4QI_type_node,
+                                   V2HI_type_node, V2HI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_V2HI_FTYPE_SI_SI]
+       = build_function_type_list (V2HI_type_node,
+                                   intSI_type_node, intSI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_SI_FTYPE_V2HI]
+       = build_function_type_list (intSI_type_node,
+                                   V2HI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_V2HI_FTYPE_V4QI]
+       = build_function_type_list (V2HI_type_node,
+                                   V4QI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_V4QI_FTYPE_V4QI_SI]
+       = build_function_type_list (V4QI_type_node,
+                                   V4QI_type_node, intSI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_V2HI_FTYPE_V2HI_SI]
+       = build_function_type_list (V2HI_type_node,
+                                   V2HI_type_node, intSI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_V2HI_FTYPE_V4QI_V2HI]
+       = build_function_type_list (V2HI_type_node,
+                                   V4QI_type_node, V2HI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_SI_FTYPE_V2HI_V2HI]
+       = build_function_type_list (intSI_type_node,
+                                   V2HI_type_node, V2HI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_DI_FTYPE_DI_V4QI_V4QI]
+       = build_function_type_list (intDI_type_node,
+                                   intDI_type_node, V4QI_type_node, V4QI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_DI_FTYPE_DI_V2HI_V2HI]
+       = build_function_type_list (intDI_type_node,
+                                   intDI_type_node, V2HI_type_node, V2HI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_DI_FTYPE_DI_SI_SI]
+       = build_function_type_list (intDI_type_node,
+                                   intDI_type_node, intSI_type_node, intSI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_V4QI_FTYPE_SI]
+       = build_function_type_list (V4QI_type_node,
+                                   intSI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_V2HI_FTYPE_SI]
+       = build_function_type_list (V2HI_type_node,
+                                   intSI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_VOID_FTYPE_V4QI_V4QI]
+       = build_function_type_list (void_type_node,
+                                   V4QI_type_node, V4QI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_SI_FTYPE_V4QI_V4QI]
+       = build_function_type_list (intSI_type_node,
+                                   V4QI_type_node, V4QI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_VOID_FTYPE_V2HI_V2HI]
+       = build_function_type_list (void_type_node,
+                                   V2HI_type_node, V2HI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_SI_FTYPE_DI_SI]
+       = build_function_type_list (intSI_type_node,
+                                   intDI_type_node, intSI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_DI_FTYPE_DI_SI]
+       = build_function_type_list (intDI_type_node,
+                                   intDI_type_node, intSI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_VOID_FTYPE_SI_SI]
+       = build_function_type_list (void_type_node,
+                                   intSI_type_node, intSI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_SI_FTYPE_PTR_SI]
+       = build_function_type_list (intSI_type_node,
+                                   ptr_type_node, intSI_type_node,
+                                   NULL_TREE);
+
+      types[MIPS_SI_FTYPE_VOID]
+       = build_function_type (intSI_type_node, void_list_node);
+    }
+
+  /* Iterate through all of the bdesc arrays, initializing all of the
+     builtin functions.  */
+
+  offset = 0;
+  for (m = bdesc_arrays; m < &bdesc_arrays[ARRAY_SIZE (bdesc_arrays)]; m++)
+    {
+      if (m->proc == PROCESSOR_MAX || (m->proc == mips_arch))
+       for (d = m->bdesc; d < &m->bdesc[m->size]; d++)
+         if ((d->target_flags & target_flags) == d->target_flags)
+           lang_hooks.builtin_function (d->name, types[d->function_type],
+                                        d - m->bdesc + offset,
+                                        BUILT_IN_MD, NULL, NULL);
+      offset += m->size;
+    }
+}
+
+/* Expand a MIPS_BUILTIN_DIRECT function.  ICODE is the code of the
+   .md pattern and ARGLIST is the list of function arguments.  TARGET,
+   if nonnull, suggests a good place to put the result.
+   HAS_TARGET indicates the function must return something.  */
 
-  /* Let op2 be the same as the tmode */
-  if (!(*insn_data[icode].operand[0].predicate) (op2, tmode))
-    op2 = copy_to_mode_reg (tmode, op2);
+static rtx
+mips_expand_builtin_direct (enum insn_code icode, rtx target, tree arglist,
+                           bool has_target)
+{
+  rtx ops[MAX_RECOG_OPERANDS];
+  int i = 0;
 
-  /* Let op3 be the same as the tmode */
-  if (!(*insn_data[icode].operand[0].predicate) (op3, tmode))
-    op3 = copy_to_mode_reg (tmode, op3);
+  if (has_target)
+    {
+      /* We save target to ops[0].  */
+      ops[0] = mips_prepare_builtin_target (icode, 0, target);
+      i = 1;
+    }
 
-  /* Copy op2 to target */
-  emit_insn (gen_rtx_SET (tmode, target, op2)); 
+  /* We need to test if arglist is not zero.  Some instructions have extra
+     clobber registers.  */
+  for (; i < insn_data[icode].n_operands && arglist != 0; i++)
+    ops[i] = mips_prepare_builtin_arg (icode, i, &arglist);
 
-  test_code = EQ;
-  compare_value = 0;
-  switch (cmp_choice)
+  switch (i)
     {
-    case MIPS_CMP_MOVT:
-      src1 = op3;
-      src2 = target;
+    case 2:
+      emit_insn (GEN_FCN (icode) (ops[0], ops[1]));
       break;
 
-    case MIPS_CMP_MOVF:
-      src1 = target;
-      src2 = op3;
+    case 3:
+      emit_insn (GEN_FCN (icode) (ops[0], ops[1], ops[2]));
+      break;
+
+    case 4:
+      emit_insn (GEN_FCN (icode) (ops[0], ops[1], ops[2], ops[3]));
       break;
 
     default:
-      return 0;
+      gcc_unreachable ();
     }
+  return target;
+}
 
-  emit_insn (gen_mips_cond_move_tf_ps (target, src1, src2, temp_target));
+/* Expand a __builtin_mips_movt_*_ps() or __builtin_mips_movf_*_ps()
+   function (TYPE says which).  ARGLIST is the list of arguments to the
+   function, ICODE is the instruction that should be used to compare
+   the first two arguments, and COND is the condition it should test.
+   TARGET, if nonnull, suggests a good place to put the result.  */
 
+static rtx
+mips_expand_builtin_movtf (enum mips_builtin_type type,
+                          enum insn_code icode, enum mips_fp_condition cond,
+                          rtx target, tree arglist)
+{
+  rtx cmp_result, op0, op1;
+
+  cmp_result = mips_prepare_builtin_target (icode, 0, 0);
+  op0 = mips_prepare_builtin_arg (icode, 1, &arglist);
+  op1 = mips_prepare_builtin_arg (icode, 2, &arglist);
+  emit_insn (GEN_FCN (icode) (cmp_result, op0, op1, GEN_INT (cond)));
+
+  icode = CODE_FOR_mips_cond_move_tf_ps;
+  target = mips_prepare_builtin_target (icode, 0, target);
+  if (type == MIPS_BUILTIN_MOVT)
+    {
+      op1 = mips_prepare_builtin_arg (icode, 2, &arglist);
+      op0 = mips_prepare_builtin_arg (icode, 1, &arglist);
+    }
+  else
+    {
+      op0 = mips_prepare_builtin_arg (icode, 1, &arglist);
+      op1 = mips_prepare_builtin_arg (icode, 2, &arglist);
+    }
+  emit_insn (gen_mips_cond_move_tf_ps (target, op0, op1, cmp_result));
   return target;
 }
 
-/* This performs two paired single compares, and returns an boolean value to
-   represent the result of the compare.  CMP_CHOICE is the kind of comparison
-   we want.  TARGET is a suggestion of where to put the result.  FCODE is
-   the builtin function code.  ARGLIST is the list of arguments.  The
-   return value is the result of the compare.  */
+/* Expand a comparison builtin of type BUILTIN_TYPE.  ICODE is the code
+   of the comparison instruction and COND is the condition it should test.
+   ARGLIST is the list of function arguments and TARGET, if nonnull,
+   suggests a good place to put the boolean result.  */
 
-rtx
-mips_expand_4s_compare_builtin (enum mips_cmp_choice cmp_choice, rtx target,
-                               unsigned int fcode, tree arglist)
+static rtx
+mips_expand_builtin_compare (enum mips_builtin_type builtin_type,
+                            enum insn_code icode, enum mips_fp_condition cond,
+                            rtx target, tree arglist)
 {
-  rtx pat;
-  enum insn_code icode;
-  tree arg0;
-  tree arg1;
-  tree arg2;
-  tree arg3;
-  rtx op0;
-  rtx op1;
-  rtx op2;
-  rtx op3;
-  enum machine_mode tmode;
-  enum machine_mode mode0;
-  enum machine_mode mode1;
-  enum machine_mode mode2;
-  enum machine_mode mode3;
-  rtx temp_target;
-  rtx label1;
-  rtx label2;
-  rtx if_then_else;
-  enum rtx_code test_code;
-  int compare_value;
+  rtx label1, label2, if_then_else;
+  rtx pat, cmp_result, ops[MAX_RECOG_OPERANDS];
+  rtx target_if_equal, target_if_unequal;
+  int cmp_value, i;
 
   if (target == 0 || GET_MODE (target) != SImode)
     target = gen_reg_rtx (SImode);
 
-  icode = mips_bdesc[fcode].icode;
-  arg0 = TREE_VALUE (arglist);
-  arg1 = TREE_VALUE (TREE_CHAIN (arglist));
-  arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
-  arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
-  op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
-  op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
-  op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
-  op3 = expand_expr (arg3, NULL_RTX, VOIDmode, 0);
-  tmode = insn_data[icode].operand[0].mode;
-  mode0 = insn_data[icode].operand[1].mode;
-  mode1 = insn_data[icode].operand[2].mode;
-  mode2 = insn_data[icode].operand[3].mode;
-  mode3 = insn_data[icode].operand[4].mode;
-
-  temp_target = gen_reg_rtx (tmode);
-
-  if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
-    op0 = copy_to_mode_reg (mode0, op0);
-
-  if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
-    op1 = copy_to_mode_reg (mode1, op1);
-
-  if (!(*insn_data[icode].operand[3].predicate) (op2, mode2))
-    op2 = copy_to_mode_reg (mode2, op2);
-
-  if (!(*insn_data[icode].operand[4].predicate) (op3, mode3))
-    op3 = copy_to_mode_reg (mode3, op3);
-
-  pat = GEN_FCN (icode) (temp_target, op0, op1, op2, op3);
-  if (!pat)
-    return 0;
+  /* Prepare the operands to the comparison.  */
+  cmp_result = mips_prepare_builtin_target (icode, 0, 0);
+  for (i = 1; i < insn_data[icode].n_operands - 1; i++)
+    ops[i] = mips_prepare_builtin_arg (icode, i, &arglist);
 
-  /* We fake the value of CCV4 to be
-     0, if ANY is true    <-->  NOT 0, if ALL is false
-     1, if ALL is true    <-->  NOT 1, if ANY is false
-     Thus, we can map "enum mips_cmp_choice" to RTL comparison operators:
-     MIPS_CMP_ANY ->   (EQ 0)
-     MIPS_CMP_ALL ->   (EQ 1)
-
-     However, because MIPS doesn't have "branch_all" instructions, 
-     for MIPS_CMP_ALL, we will use (NE 1) and reverse the assignment of 
-     the target to 1 first and then 0.  */
-  switch (cmp_choice)
-    {
-    case MIPS_CMP_ANY:
-      test_code = EQ;
-      compare_value = 0;
+  switch (insn_data[icode].n_operands)
+    {
+    case 4:
+      pat = GEN_FCN (icode) (cmp_result, ops[1], ops[2], GEN_INT (cond));
       break;
 
-    case MIPS_CMP_ALL:
-      test_code = NE;
-      compare_value = 1;
+    case 6:
+      pat = GEN_FCN (icode) (cmp_result, ops[1], ops[2],
+                            ops[3], ops[4], GEN_INT (cond));
       break;
 
     default:
-      return 0;
+      gcc_unreachable ();
     }
 
-  if (cmp_choice == MIPS_CMP_ALL)
-    emit_move_insn (target, const1_rtx);
+  /* If the comparison sets more than one register, we define the result
+     to be 0 if all registers are false and -1 if all registers are true.
+     The value of the complete result is indeterminate otherwise.  It is
+     possible to test individual registers using SUBREGs.
+
+     Set up CMP_RESULT, CMP_VALUE, TARGET_IF_EQUAL and TARGET_IF_UNEQUAL so
+     that the result should be TARGET_IF_EQUAL if (EQ CMP_RESULT CMP_VALUE)
+     and TARGET_IF_UNEQUAL otherwise.  */
+  if (builtin_type == MIPS_BUILTIN_CMP_ALL)
+    {
+      cmp_value = -1;
+      target_if_equal = const1_rtx;
+      target_if_unequal = const0_rtx;
+    }
   else
-    emit_move_insn (target, const0_rtx);
+    {
+      cmp_value = 0;
+      target_if_equal = const0_rtx;
+      target_if_unequal = const1_rtx;
+      if (builtin_type == MIPS_BUILTIN_CMP_UPPER)
+       cmp_result = simplify_gen_subreg (CCmode, cmp_result, CCV2mode, 4);
+      else if (builtin_type == MIPS_BUILTIN_CMP_LOWER)
+       cmp_result = simplify_gen_subreg (CCmode, cmp_result, CCV2mode, 0);
+    }
 
-  emit_insn (pat);
+  /* First assume that CMP_RESULT == CMP_VALUE.  */
+  emit_move_insn (target, target_if_equal);
 
+  /* Branch to LABEL1 if CMP_RESULT != CMP_VALUE.  */
+  emit_insn (pat);
   label1 = gen_label_rtx ();
   label2 = gen_label_rtx ();
-  if_then_else 
+  if_then_else
     = gen_rtx_IF_THEN_ELSE (VOIDmode,
-                           gen_rtx_fmt_ee (test_code, CCV4mode, temp_target, 
-                                           GEN_INT (compare_value)),
+                           gen_rtx_fmt_ee (NE, GET_MODE (cmp_result),
+                                           cmp_result, GEN_INT (cmp_value)),
                            gen_rtx_LABEL_REF (VOIDmode, label1), pc_rtx);
-
-  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, if_then_else)); 
-  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, 
+  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, if_then_else));
+  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
                               gen_rtx_LABEL_REF (VOIDmode, label2)));
-
   emit_barrier ();
   emit_label (label1);
 
-  if (cmp_choice == MIPS_CMP_ALL)
-    emit_move_insn (target, const0_rtx);
-  else
-    emit_move_insn (target, const1_rtx);
-
+  /* Fix TARGET for CMP_RESULT != CMP_VALUE.  */
+  emit_move_insn (target, target_if_unequal);
   emit_label (label2);
 
   return target;
 }
 
-/* This performs a single float or double float comparison.  TARGET is a
-   suggestion of where to put the result.  FCODE is the builtin function code.
-   ARGLIST is the list of arguments.  The return value is the result of the
-   compare.  */
+/* Expand a bposge builtin of type BUILTIN_TYPE.  TARGET, if nonnull,
+   suggests a good place to put the boolean result.
 
-rtx
-mips_expand_compare_builtin (rtx target, unsigned int fcode, tree arglist)
+   The sequence we want is
+
+       li      target, 0
+       bposge* label1
+       j       label2
+   label1:
+       li      target, 1
+   label2:  */
+
+static rtx
+mips_expand_builtin_bposge (enum mips_builtin_type builtin_type, rtx target)
 {
-  rtx pat;
-  enum insn_code icode;
-  tree arg0;
-  tree arg1;
-  rtx op0;
-  rtx op1;
-  enum machine_mode tmode;
-  enum machine_mode mode0;
-  enum machine_mode mode1;
-  rtx temp_target;
-  rtx label1;
-  rtx label2;
-  rtx if_then_else;
-  enum rtx_code test_code;
+  rtx label1, label2, if_then_else;
+  rtx cmp_result;
+  int cmp_value;
 
   if (target == 0 || GET_MODE (target) != SImode)
     target = gen_reg_rtx (SImode);
 
-  icode = mips_bdesc[fcode].icode;
-  arg0 = TREE_VALUE (arglist);
-  arg1 = TREE_VALUE (TREE_CHAIN (arglist));
-  op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
-  op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
-  tmode = insn_data[icode].operand[0].mode;
-  mode0 = insn_data[icode].operand[1].mode;
-  mode1 = insn_data[icode].operand[2].mode;
-
-  temp_target = gen_reg_rtx (tmode);
+  cmp_result = gen_rtx_REG (CCDSPmode, CCDSP_PO_REGNUM);
 
-  if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
-    op0 = copy_to_mode_reg (mode0, op0);
-
-  if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
-    op1 = copy_to_mode_reg (mode1, op1);
-
-  pat = GEN_FCN (icode) (temp_target, op0, op1);
-  if (!pat)
-    return 0;
+  if (builtin_type == MIPS_BUILTIN_BPOSGE32)
+    cmp_value = 32;
+  else
+    gcc_assert (0);
 
+  /* Move 0 to target */
   emit_move_insn (target, const0_rtx);
-  emit_insn (pat);
 
+  /* Generate two labels */
   label1 = gen_label_rtx ();
   label2 = gen_label_rtx ();
 
-  test_code =  NE;
+  /* Generate if_then_else */
   if_then_else
     = gen_rtx_IF_THEN_ELSE (VOIDmode,
-                           gen_rtx_fmt_ee (test_code, CCmode, 
-                                           temp_target, const0_rtx),
+                           gen_rtx_fmt_ee (GE, CCDSPmode,
+                                           cmp_result, GEN_INT (cmp_value)),
                            gen_rtx_LABEL_REF (VOIDmode, label1), pc_rtx);
 
-  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, if_then_else)); 
-  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, 
-                              gen_rtx_LABEL_REF (VOIDmode, label2)));
-
+  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, if_then_else));
+  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
+                               gen_rtx_LABEL_REF (VOIDmode, label2)));
   emit_barrier ();
   emit_label (label1);
   emit_move_insn (target, const1_rtx);
@@ -10962,129 +10745,21 @@ mips_expand_compare_builtin (rtx target, unsigned int fcode, tree arglist)
 
   return target;
 }
+\f
+/* Set SYMBOL_REF_FLAGS for the SYMBOL_REF inside RTL, which belongs to DECL.
+   FIRST is true if this is the first time handling this decl.  */
 
-/* This performs a paired single compare, and returns an boolean value to
-   represent the result of the compare.  CMP_CHOICE is the kind of comparison
-   we want.  TARGET is a suggestion of where to put the result.  FCODE is
-   the builtin function code.  ARGLIST is the list of arguments.  The
-   return value is the result of the compare.  */
-
-rtx
-mips_expand_ps_compare_builtin (enum mips_cmp_choice cmp_choice, rtx target,
-                               unsigned int fcode, tree arglist)
+static void
+mips_encode_section_info (tree decl, rtx rtl, int first)
 {
-  rtx pat;
-  enum insn_code icode;
-  tree arg0;
-  tree arg1;
-  rtx op0;
-  rtx op1;
-  enum machine_mode tmode;
-  enum machine_mode mode0;
-  enum machine_mode mode1;
-  rtx temp_target;
-  rtx label1;
-  rtx label2;
-  rtx if_then_else;
-  enum rtx_code test_code;
-  int compare_value;
-
-  if (target == 0 || GET_MODE (target) != SImode)
-    target = gen_reg_rtx (SImode);
-
-  icode = mips_bdesc[fcode].icode;
-  arg0 = TREE_VALUE (arglist);
-  arg1 = TREE_VALUE (TREE_CHAIN (arglist));
-  op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
-  op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
-  tmode = insn_data[icode].operand[0].mode;
-  mode0 = insn_data[icode].operand[1].mode;
-  mode1 = insn_data[icode].operand[2].mode;
-
-  temp_target = gen_reg_rtx (tmode);
-
-  if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
-    op0 = copy_to_mode_reg (mode0, op0);
-
-  if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
-    op1 = copy_to_mode_reg (mode1, op1);
-
-  pat = GEN_FCN (icode) (temp_target, op0, op1);
-  if (!pat)
-    return 0;
-
-  /* We fake the value of CCV2 to be
-     0, if ANY is true    <-->  NOT 0, if ALL is false
-     1, if UPPER is true  <-->  NOT 1, if UPPER is false
-     2, if LOWER is true  <-->  NOT 2, if LOWER is false
-     3, if ALL is true    <-->  NOT 3, if ANY is false
-     Thus, we can map "enum mips_cmp_choice" to RTL comparison operators:
-     MIPS_CMP_ANY ->   (EQ 0)
-     MIPS_CMP_UPPER -> (EQ 1)
-     MIPS_CMP_LOWER -> (EQ 2)
-     MIPS_CMP_ALL ->   (EQ 3)
-
-     However, because MIPS doesn't have "branch_all" instructions, 
-     for MIPS_CMP_ALL, we will use (NE 3) and reverse the assignment of 
-     the target to 1 fisrt and then 0.  */
-  switch (cmp_choice)
-    {
-    case MIPS_CMP_ANY:
-      test_code = EQ;
-      compare_value = 0;
-      break;
-
-    case MIPS_CMP_UPPER:
-      test_code = EQ;
-      compare_value = 1;
-      break;
-
-    case MIPS_CMP_LOWER:
-      test_code = EQ;
-      compare_value = 2;
-      break;
-
-    case MIPS_CMP_ALL:
-      test_code = NE;
-      compare_value = 3;
-      break;
+  default_encode_section_info (decl, rtl, first);
 
-    default:
-      return 0;
+  if (TREE_CODE (decl) == FUNCTION_DECL
+      && lookup_attribute ("long_call", TYPE_ATTRIBUTES (TREE_TYPE (decl))))
+    {
+      rtx symbol = XEXP (rtl, 0);
+      SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_LONG_CALL;
     }
-
-  if (cmp_choice == MIPS_CMP_ALL)
-    emit_move_insn (target, const1_rtx);
-  else
-    emit_move_insn (target, const0_rtx);
-
-  emit_insn (pat);
-
-  label1 = gen_label_rtx ();
-  label2 = gen_label_rtx ();
-
-  if_then_else 
-    = gen_rtx_IF_THEN_ELSE (VOIDmode,
-                           gen_rtx_fmt_ee (test_code, CCV2mode, temp_target, 
-                                           GEN_INT (compare_value)),
-                           gen_rtx_LABEL_REF (VOIDmode, label1), pc_rtx);
-
-  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, if_then_else)); 
-  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, 
-                              gen_rtx_LABEL_REF (VOIDmode, label2)));
-
-  emit_barrier ();
-  emit_label (label1);
-
-  if (cmp_choice == MIPS_CMP_ALL)
-    emit_move_insn (target, const0_rtx);
-  else
-    emit_move_insn (target, const1_rtx);
-
-  emit_label (label2);
-
-  return target;
 }
 \f
 #include "gt-mips.h"