[PATCH] MIPS32 DSP intrinsics

Fu, Chao-Ying fu@mips.com
Tue May 24 23:04:00 GMT 2005


Hello,

  Here is the patch for MIPS32 DSP intrinsics.
Can anyone commit the patch?  Thanks!

Regards,
Chao-ying

2005-05-24  Chao-ying Fu  <fu@mips.com>

	* config/mips/mips-modes.def (V4QI, V2HI, CCDSP): New modes.

	* config/mips/mips.h (FIRST_PSEUDO_REGISTER): Increase to 188 because
	of adding 6 dsp accumulator registers and 6 dsp control registers.
	(FIXED_REGISTERS, CALL_USED_REGISTERS, CALL_REALLY_USED_REGISTERS):
	Update for 12 new dsp registers.
	(DSP_ACC_REG_FIRST, DSP_ACC_REG_LAST, DSP_ACC_REG_NUM,
	DSP_CONTROL_PO_REGNUM, DSP_CONTROL_SC_REGNUM, DSP_CONTROL_CA_REGNUM,
	DSP_CONTROL_OU_REGNUM, DSP_CONTROL_CC_REGNUM, DSP_CONTROL_EF_REGNUM,
	DSP_ACC_REG_P): New define.
	(reg_class): Add DSP_ACC_REGS, MD_AND_DSP_ACC_REGS, and DSP_CNTL_REGS.
	(REG_CLASS_NAMES): Add names for DSP_ACC_REGS, MD_AND_DSP_ACC_REGS, and
	DSP_CNTL_REGS.
	(REG_CLASS_CONTENTS): Update for DSP_ACC_REGS, MD_AND_DSP_ACC_REGS, and
	DSP_CNTL_REGS.
	(REG_ALLOC_ORDER): Update for 12 new dsp registers.
	(mips_char_to_class): Add 'a' for MD and DSP accumulator registers.
	(mips_args): Update for 12 new dsp registers.

	* config/mips/mips.c (mips_function_type): Add types for dsp intrinsics.
	(mips_builtin_type): Add MIPS_BUILTIN_DIRECT_IMM*, 
	MIPS_BUILTIN_DIRECT_NO_TARGET, MIPS_BUILTIN_DIRECT_NO_TARGET_IMM*,
	MIPS_BUILTIN_BPOSGE32 for dsp intrinsics.
	(mips_prepare_builtin_arg): Add 2 more parameters.
	(mips_expand_builtin_direct): Add 3 more parameters.
	(mips_expand_builtin_bposge): New for expanding bposge.
	(mips_regno_to_class): Update for 12 new dsp registers.
	(mips_subword): Check dsp accumulator registers.
	(mips_output_move): Output move for dsp accumulator registers.
	(override_options): Map 'a' to MD_AND_DSP_ACC_REGS.  Enable dsp
	accumulator registers for machine modes.
	(print_operand): Add 'q' for printing dsp accumulator registers.
	(mips_cannot_change_mode_class): Check DSP_ACC_REGS.
	(mips_secondary_reload_class): Check dsp accumulator registers.
	(mips_vector_mode_supported_p): Enable V2HI and V4QI when TARGET_DSP.
	(mips_register_move_cost): Check dsp accumulator registers.
	(CODE_FOR_mips_addq_ph, CODE_FOR_mips_addu_qb, CODE_FOR_mips_subq_ph,
	CODE_FOR_mips_subu_qb, CODE_FOR_mips_bposge32): New define.
	(MIPS_BUILTIN_DIRECT_IMM, DIRECT_BUILTIN_NO_TARGET,
	DIRECT_BUILTIN_NO_TARGET_IMM, BPOSGE_BUILTIN): New define.
	(dsp_bdesc): New for dsp intrinsics.
	(bdesc_arrays): Add dsp intrinsics.
	(mips_prepare_builtin_arg): Check constant operands in the specific
	range.
	(mips_expand_builtin): Support new builtin types.
	(mips_init_builtins): Support new dsp builtins.
	(mips_expand_builtin_direct): Check if target is needed, and arglist
	is valid.
	(mips_expand_builtin_movtf, mips_expand_builtin_compare): Add two
	parameters for mips_prepare_builtin_arg.
	(mips_expand_builtin_bposge): New for expanding bposge*.

	* config/mips/mips.md (UNSPEC_ADDQ_PH .. UNSPEC_RDDSP): New.
	(*movdi_32bit): Add dsp accumulator registers.
	(*movsi_internal): Add dsp accumulator registers.
	(mips-dsp.md): New include.

	* config/mips/mips.opt (mdsp): New option.

	* config/mips/mips-dsp.md: New file.

Index: config/mips/mips-modes.def
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/mips/mips-modes.def,v
retrieving revision 1.3
diff -c -3 -p -r1.3 mips-modes.def
*** config/mips/mips-modes.def	17 Oct 2004 18:09:42 -0000	1.3
--- config/mips/mips-modes.def	24 May 2005 22:41:17 -0000
*************** FLOAT_MODE (TF, 16, mips_quad_format);
*** 28,33 ****
--- 28,34 ----
  
  /* Vector modes.  */
  VECTOR_MODES (FLOAT, 8);      /*            V4HF V2SF */
+ VECTOR_MODES (INT, 4);        /*            V4QI V2HI */
  
  /* Paired single comparison instructions use 2 or 4 CC.  */
  CC_MODE (CCV2);
*************** ADJUST_ALIGNMENT (CCV2, 8);
*** 37,39 ****
--- 38,43 ----
  CC_MODE (CCV4);
  ADJUST_BYTESIZE (CCV4, 16);
  ADJUST_ALIGNMENT (CCV4, 16);
+ 
+ /* For MIPS DSP ASE */
+ CC_MODE (CCDSP);
Index: config/mips/mips.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/mips/mips.c,v
retrieving revision 1.503
diff -c -3 -p -r1.503 mips.c
*** config/mips/mips.c	13 May 2005 15:24:29 -0000	1.503
--- config/mips/mips.c	24 May 2005 22:41:18 -0000
*************** enum mips_function_type
*** 150,155 ****
--- 150,184 ----
    MIPS_DF_FTYPE_DF,
    MIPS_DF_FTYPE_DF_DF,
  
+   /* For MIPS DSP ASE  */
+   MIPS_V2HI_FTYPE_V2HI_V2HI,
+   MIPS_SI_FTYPE_SI_SI,
+   MIPS_V4QI_FTYPE_V4QI_V4QI,
+   MIPS_SI_FTYPE_V4QI,
+   MIPS_V2HI_FTYPE_V2HI,
+   MIPS_SI_FTYPE_SI,
+   MIPS_V4QI_FTYPE_V2HI_V2HI,
+   MIPS_V2HI_FTYPE_SI_SI,
+   MIPS_SI_FTYPE_V2HI,
+   MIPS_V2HI_FTYPE_V4QI,
+   MIPS_V4QI_FTYPE_V4QI_SI,
+   MIPS_V2HI_FTYPE_V2HI_SI,
+   MIPS_V2HI_FTYPE_V4QI_V2HI,
+   MIPS_SI_FTYPE_V2HI_V2HI,
+   MIPS_DI_FTYPE_DI_V4QI_V4QI,
+   MIPS_DI_FTYPE_DI_V2HI_V2HI,
+   MIPS_DI_FTYPE_DI_SI_SI,
+   MIPS_V4QI_FTYPE_SI,
+   MIPS_V2HI_FTYPE_SI,
+   MIPS_VOID_FTYPE_V4QI_V4QI,
+   MIPS_SI_FTYPE_V4QI_V4QI,
+   MIPS_VOID_FTYPE_V2HI_V2HI,
+   MIPS_SI_FTYPE_DI_SI,
+   MIPS_DI_FTYPE_DI_SI,
+   MIPS_VOID_FTYPE_SI_SI,
+   MIPS_SI_FTYPE_PTR_SI,
+   MIPS_SI_FTYPE_VOID,
+ 
    /* The last type.  */
    MIPS_MAX_FTYPE_MAX
  };
*************** enum mips_builtin_type
*** 162,167 ****
--- 191,236 ----
       operands 1 and above.  */
    MIPS_BUILTIN_DIRECT,
  
+   /* Similar to MIPS_BUILTIN_DIRECT, but the last argument is an immediate 
+      from 0 to 7.  */
+   MIPS_BUILTIN_DIRECT_IMM0_7,
+ 
+   /* Similar to MIPS_BUILTIN_DIRECT, but the last argument is an immediate 
+      from 0 to 15.  */
+   MIPS_BUILTIN_DIRECT_IMM0_15,
+ 
+   /* Similar to MIPS_BUILTIN_DIRECT, but the last argument is an immediate 
+      from 0 to 31.  */
+   MIPS_BUILTIN_DIRECT_IMM0_31,
+ 
+   /* Similar to MIPS_BUILTIN_DIRECT, but the last argument is an immediate 
+      from 1 to 32.  */
+   MIPS_BUILTIN_DIRECT_IMM1_32,
+ 
+   /* Similar to MIPS_BUILTIN_DIRECT, but the last argument is an immediate 
+      from 0 to 63.  */
+   MIPS_BUILTIN_DIRECT_IMM0_63,
+ 
+   /* Similar to MIPS_BUILTIN_DIRECT, but the last argument is an immediate 
+      from -32 to 31.  */
+   MIPS_BUILTIN_DIRECT_IMMn32_31,
+ 
+   /* Similar to MIPS_BUILTIN_DIRECT, but the last argument is an immediate 
+      from 0 to 255.  */
+   MIPS_BUILTIN_DIRECT_IMM0_255,
+ 
+   /* Similar to MIPS_BUILTIN_DIRECT, but the last argument is an immediate 
+      from 0 to 1023.  */
+   MIPS_BUILTIN_DIRECT_IMM0_1023,
+ 
+   /* 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,
+ 
+   /* Similar to MIPS_BUILTIN_DIRECT_NO_TARGET, but the last argument is an 
+      immediate from 0 to 63.  */
+   MIPS_BUILTIN_DIRECT_NO_TARGET_IMM0_63,
+ 
    /* 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
*************** enum mips_builtin_type
*** 185,191 ****
    MIPS_BUILTIN_CMP_LOWER,
  
    /* As above, but the instruction only sets a single $fcc register.  */
!   MIPS_BUILTIN_CMP_SINGLE
  };
  
  /* Invokes MACRO (COND) for each c.cond.fmt condition.  */
--- 254,263 ----
    MIPS_BUILTIN_CMP_LOWER,
  
    /* As above, but the instruction only sets a single $fcc register.  */
!   MIPS_BUILTIN_CMP_SINGLE,
! 
!   /* For BPOSGE32 */
!   MIPS_BUILTIN_BPOSGE32
  };
  
  /* Invokes MACRO (COND) for each c.cond.fmt condition.  */
*************** static int mips_arg_partial_bytes (CUMUL
*** 358,374 ****
  				   tree, bool);
  static bool mips_valid_pointer_mode (enum machine_mode);
  static bool mips_vector_mode_supported_p (enum machine_mode);
! 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 void mips_init_builtins (void);
! static rtx mips_expand_builtin_direct (enum insn_code, rtx, tree);
  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);
  
  /* Structure to be filled in by compute_frame_size with register
     save masks, and offsets for the current function.  */
--- 430,449 ----
  				   tree, bool);
  static bool mips_valid_pointer_mode (enum machine_mode);
  static bool mips_vector_mode_supported_p (enum machine_mode);
! static rtx mips_prepare_builtin_arg (enum insn_code, unsigned int, tree *,
! 				     int, int);
  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 void mips_init_builtins (void);
! static rtx mips_expand_builtin_direct (enum insn_code, rtx, tree, int, 
! 				       int, int);
  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);
  
  /* Structure to be filled in by compute_frame_size with register
     save masks, and offsets for the current function.  */
*************** const enum reg_class mips_regno_to_class
*** 643,649 ****
    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
  };
  
  /* Map register constraint character to register class.  */
--- 718,727 ----
    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,	DSP_CNTL_REGS,	DSP_CNTL_REGS,
!   DSP_CNTL_REGS,DSP_CNTL_REGS,	DSP_CNTL_REGS,	DSP_CNTL_REGS
  };
  
  /* Map register constraint character to register class.  */
*************** mips_subword (rtx op, int high_p)
*** 2422,2427 ****
--- 2500,2507 ----
  	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 (DSP_ACC_REG_P (REGNO (op)))
+ 	return gen_rtx_REG (word_mode, high_p ? REGNO (op) : REGNO (op) + 1);
      }
  
    if (MEM_P (op))
*************** mips_output_move (rtx dest, rtx src)
*** 2535,2540 ****
--- 2615,2628 ----
  	  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");
  
*************** mips_output_move (rtx dest, rtx src)
*** 2553,2558 ****
--- 2641,2657 ----
      {
        if (src_code == REG)
  	{
+ 	  if (MD_REG_P (REGNO (src)))
+ 	    return "mf%1\t%0";
+ 
+ 	  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";
  
*************** override_options (void)
*** 4529,4534 ****
--- 4628,4634 ----
    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'] = (TARGET_DSP ? MD_AND_DSP_ACC_REGS : NO_REGS);;
  
    /* Set up array to map GCC register number to debug register number.
       Ignore the special purpose register numbers.  */
*************** override_options (void)
*** 4600,4605 ****
--- 4700,4712 ----
  			|| (regno == MD_REG_FIRST
  			    && size == 2 * UNITS_PER_WORD)));
  
+           else if (DSP_ACC_REG_P (regno))
+             temp = (TARGET_DSP && !TARGET_MIPS16
+ 		    && INTEGRAL_MODE_P (mode)
+ 		    && (size <= UNITS_PER_WORD
+ 			|| (((regno - DSP_ACC_REG_FIRST) & 1) == 0
+ 			     && size == 2 * UNITS_PER_WORD)));
+ 
  	  else if (ALL_COP_REG_P (regno))
  	    temp = (class == MODE_INT && size <= UNITS_PER_WORD);
  	  else
*************** mips_debugger_offset (rtx addr, HOST_WID
*** 4890,4895 ****
--- 4997,5003 ----
     '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
+    'q'  print DSP accumulator registers
  
     The punctuation characters are:
  
*************** print_operand (FILE *file, rtx op, int l
*** 5140,5145 ****
--- 5248,5269 ----
  	}
      }
  
+   else if (letter == 'q')
+     {
+       register int regnum;
+ 
+       if (code != REG)
+ 	fatal_insn ("PRINT_OPERAND, invalid insn for %%q", op);
+ 
+       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)
      {
        register int regnum;
*************** mips_cannot_change_mode_class (enum mach
*** 7089,7094 ****
--- 7213,7220 ----
  	     and multi-word modes.  */
  	  if (reg_classes_intersect_p (HI_REG, class))
  	    return true;
+ 	  if (reg_classes_intersect_p (DSP_ACC_REGS, class))
+ 	    return true;
  	}
      }
    /* Loading a 32-bit value into a 64-bit floating-point register
*************** mips_secondary_reload_class (enum reg_cl
*** 7169,7175 ****
  
    /* 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)
      {
        if (TARGET_MIPS16 && in_p)
  	{
--- 7295,7302 ----
  
    /* 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 ||
!       class == DSP_ACC_REGS || class == MD_AND_DSP_ACC_REGS)
      {
        if (TARGET_MIPS16 && in_p)
  	{
*************** mips_secondary_reload_class (enum reg_cl
*** 7178,7184 ****
  	}
        return gp_reg_p ? NO_REGS : gr_regs;
      }
!   if (MD_REG_P (regno))
      {
        if (TARGET_MIPS16 && ! in_p)
  	{
--- 7305,7311 ----
  	}
        return gp_reg_p ? NO_REGS : gr_regs;
      }
!   if (MD_REG_P (regno) || DSP_ACC_REG_P (regno))
      {
        if (TARGET_MIPS16 && ! in_p)
  	{
*************** mips_vector_mode_supported_p (enum machi
*** 7291,7296 ****
--- 7418,7425 ----
  {
    if (mode == V2SFmode && TARGET_PAIRED_SINGLE_FLOAT)
      return true;
+   else if (TARGET_DSP && (mode == V2HImode || mode == V4QImode))
+     return true;
    else
      return false;
  }
*************** mips_register_move_cost (enum machine_mo
*** 8657,8663 ****
  	}
        else if (to == FP_REGS)
  	return 4;
!       else if (to == HI_REG || to == LO_REG || to == MD_REGS)
  	{
  	  if (TARGET_MIPS16)
  	    return 12;
--- 8786,8793 ----
  	}
        else if (to == FP_REGS)
  	return 4;
!       else if (to == HI_REG || to == LO_REG || to == MD_REGS ||
! 	       to == DSP_ACC_REGS || to == MD_AND_DSP_ACC_REGS)
  	{
  	  if (TARGET_MIPS16)
  	    return 12;
*************** mips_register_move_cost (enum machine_mo
*** 8678,8684 ****
        else if (to == ST_REGS)
  	return 8;
      }  /* from == FP_REGS */
!   else if (from == HI_REG || from == LO_REG || from == MD_REGS)
      {
        if (GR_REG_CLASS_P (to))
  	{
--- 8808,8815 ----
        else if (to == ST_REGS)
  	return 8;
      }  /* from == FP_REGS */
!   else if (from == HI_REG || from == LO_REG || from == MD_REGS ||
! 	   from == DSP_ACC_REGS || from == MD_AND_DSP_ACC_REGS)
      {
        if (GR_REG_CLASS_P (to))
  	{
*************** static const struct builtin_description 
*** 9679,9684 ****
--- 9810,9962 ----
    DIRECT_BUILTIN (sqrt_ps, MIPS_V2SF_FTYPE_V2SF, MASK_PAIRED_SINGLE_FLOAT)
  };
  
+ /* 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 CODE_FOR_mips_bposge32 CODE_FOR_mips_bposge
+ 
+ /* Define a MIPS_BUILTIN_DIRECT_IMM* function for instruction 
+    CODE_FOR_mips_<INSN>.  FUNCTION_TYPE and TARGET_FLAGS are 
+    builtin_description fields.  */
+ #define DIRECT_BUILTIN_IMM(INSN, FUNCTION_TYPE, TARGET_FLAGS, MIN, MAX)	\
+   { CODE_FOR_mips_ ## INSN, 0, "__builtin_mips_" #INSN,			\
+     MIPS_BUILTIN_DIRECT_IMM ## MIN ## _ ##MAX, FUNCTION_TYPE, TARGET_FLAGS }
+ 
+ /* 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_BUILTIN_NO_TARGET(INSN, FUNCTION_TYPE, TARGET_FLAGS)	\
+   { CODE_FOR_mips_ ## INSN, 0, "__builtin_mips_" #INSN,			\
+     MIPS_BUILTIN_DIRECT_NO_TARGET, FUNCTION_TYPE, TARGET_FLAGS }
+ 
+ /* Define a MIPS_BUILTIN_DIRECT_NO_TARGET_IMM* function for instruction 
+    CODE_FOR_mips_<INSN>.  FUNCTION_TYPE and TARGET_FLAGS are 
+    builtin_description fields.  */
+ #define DIRECT_BUILTIN_NO_TARGET_IMM(INSN, FUNCTION_TYPE, TARGET_FLAGS, \
+ 				     MIN, MAX)				\
+   { CODE_FOR_mips_ ## INSN, 0, "__builtin_mips_" #INSN,			\
+     MIPS_BUILTIN_DIRECT_NO_TARGET_IMM ## MIN ## _ ## MAX, FUNCTION_TYPE,\
+     TARGET_FLAGS }
+ 
+ #define BPOSGE_BUILTIN(INSN, BUILTIN_TYPE, FUNCTION_TYPE, TARGET_FLAGS)	\
+   { CODE_FOR_mips_ ## INSN, 0, "__builtin_mips_" #INSN,			\
+     MIPS_BUILTIN_ ## BUILTIN_TYPE, FUNCTION_TYPE, 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_ph, MIPS_V2HI_FTYPE_V2HI, 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_IMM (shll_qb, MIPS_V4QI_FTYPE_V4QI_SI, MASK_DSP, 0, 7),
+   DIRECT_BUILTIN (shllv_qb, MIPS_V4QI_FTYPE_V4QI_SI, MASK_DSP),
+   DIRECT_BUILTIN_IMM (shll_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP, 0, 15),
+   DIRECT_BUILTIN (shllv_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP),
+   DIRECT_BUILTIN_IMM (shll_s_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP, 0, 15),
+   DIRECT_BUILTIN (shllv_s_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP),
+   DIRECT_BUILTIN_IMM (shll_s_w, MIPS_SI_FTYPE_SI_SI, MASK_DSP, 0, 31),
+   DIRECT_BUILTIN (shllv_s_w, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
+   DIRECT_BUILTIN_IMM (shrl_qb, MIPS_V4QI_FTYPE_V4QI_SI, MASK_DSP, 0, 7),
+   DIRECT_BUILTIN (shrlv_qb, MIPS_V4QI_FTYPE_V4QI_SI, MASK_DSP),
+   DIRECT_BUILTIN_IMM (shra_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP, 0, 15),
+   DIRECT_BUILTIN (shrav_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP),
+   DIRECT_BUILTIN_IMM (shra_r_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP, 0, 15),
+   DIRECT_BUILTIN (shrav_r_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP),
+   DIRECT_BUILTIN_IMM (shra_r_w, MIPS_SI_FTYPE_SI_SI, MASK_DSP, 0, 31),
+   DIRECT_BUILTIN (shrav_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_IMM (repl_qb, MIPS_V4QI_FTYPE_SI, MASK_DSP, 0, 255),
+   DIRECT_BUILTIN (replv_qb, MIPS_V4QI_FTYPE_SI, MASK_DSP),
+   DIRECT_BUILTIN_IMM (repl_ph, MIPS_V2HI_FTYPE_SI, MASK_DSP, 0, 1023),
+   DIRECT_BUILTIN (replv_ph, MIPS_V2HI_FTYPE_SI, MASK_DSP),
+   DIRECT_BUILTIN_NO_TARGET (cmpu_eq_qb, MIPS_VOID_FTYPE_V4QI_V4QI, MASK_DSP),
+   DIRECT_BUILTIN_NO_TARGET (cmpu_lt_qb, MIPS_VOID_FTYPE_V4QI_V4QI, MASK_DSP),
+   DIRECT_BUILTIN_NO_TARGET (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_BUILTIN_NO_TARGET (cmp_eq_ph, MIPS_VOID_FTYPE_V2HI_V2HI, MASK_DSP),
+   DIRECT_BUILTIN_NO_TARGET (cmp_lt_ph, MIPS_VOID_FTYPE_V2HI_V2HI, MASK_DSP),
+   DIRECT_BUILTIN_NO_TARGET (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_IMM (extr_w, MIPS_SI_FTYPE_DI_SI, MASK_DSP, 0, 31),
+   DIRECT_BUILTIN_IMM (extr_r_w, MIPS_SI_FTYPE_DI_SI, MASK_DSP, 0, 31),
+   DIRECT_BUILTIN_IMM (extr_rs_w, MIPS_SI_FTYPE_DI_SI, MASK_DSP, 0, 31),
+   DIRECT_BUILTIN_IMM (extr_s_h, MIPS_SI_FTYPE_DI_SI, MASK_DSP, 0, 31),
+   DIRECT_BUILTIN (extrv_s_h, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
+   DIRECT_BUILTIN (extrv_w, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
+   DIRECT_BUILTIN (extrv_r_w, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
+   DIRECT_BUILTIN (extrv_rs_w, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
+   DIRECT_BUILTIN_IMM (extl_w, MIPS_SI_FTYPE_DI_SI, MASK_DSP, 0, 31),
+   DIRECT_BUILTIN_IMM (extl_s_w, MIPS_SI_FTYPE_DI_SI, MASK_DSP, 0, 31),
+   DIRECT_BUILTIN (extlv_w, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
+   DIRECT_BUILTIN (extlv_s_w, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
+   DIRECT_BUILTIN_IMM (extp, MIPS_SI_FTYPE_DI_SI, MASK_DSP, 1, 32),
+   DIRECT_BUILTIN (extpv, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
+   DIRECT_BUILTIN_IMM (extpdp, MIPS_SI_FTYPE_DI_SI, MASK_DSP, 1, 32),
+   DIRECT_BUILTIN (extpdpv, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
+   DIRECT_BUILTIN_IMM (shilo, MIPS_DI_FTYPE_DI_SI, MASK_DSP, n32, 31),
+   DIRECT_BUILTIN (shilov, MIPS_DI_FTYPE_DI_SI, MASK_DSP),
+   DIRECT_BUILTIN (mthlip, MIPS_DI_FTYPE_DI_SI, MASK_DSP),
+   DIRECT_BUILTIN_NO_TARGET_IMM (wrdsp, MIPS_VOID_FTYPE_SI_SI, MASK_DSP, 0, 63),
+   DIRECT_BUILTIN_IMM (rddsp, MIPS_SI_FTYPE_SI, MASK_DSP, 0, 63),
+   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 (bposge32, BPOSGE32, MIPS_SI_FTYPE_VOID, MASK_DSP),
+ };
+ 
  /* This helps provide a mapping from builtin function codes to bdesc
     arrays.  */
  
*************** struct bdesc_map
*** 9698,9720 ****
  static const struct bdesc_map bdesc_arrays[] =
  {
    { mips_bdesc, ARRAY_SIZE (mips_bdesc), PROCESSOR_DEFAULT },
!   { sb1_bdesc, ARRAY_SIZE (sb1_bdesc), PROCESSOR_SB1 }
  };
  
  /* 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.  */
  
  static rtx
! mips_prepare_builtin_arg (enum insn_code icode,
! 			  unsigned int op, tree *arglist)
  {
    rtx value;
    enum machine_mode mode;
  
!   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);
  
    *arglist = TREE_CHAIN (*arglist);
--- 9976,10035 ----
  static const struct bdesc_map bdesc_arrays[] =
  {
    { mips_bdesc, ARRAY_SIZE (mips_bdesc), PROCESSOR_DEFAULT },
!   { sb1_bdesc, ARRAY_SIZE (sb1_bdesc), PROCESSOR_SB1 },
!   { dsp_bdesc, ARRAY_SIZE (dsp_bdesc), PROCESSOR_DEFAULT }
  };
  
  /* Take the head of argument list *ARGLIST and convert it into a form
!    suitable for input operand OP of instruction ICODE.  MIN and MAX are used as
!    the range only if the operand must be an immediate_operand.
!    Return the value and point *ARGLIST at the next element of the list.  */
  
  static rtx
! mips_prepare_builtin_arg (enum insn_code icode, unsigned int op, tree *arglist,
! 			  int min, int max)
  {
+   tree arg;
    rtx value;
    enum machine_mode mode;
  
!   arg = TREE_VALUE (*arglist);
!   value = expand_expr (arg, NULL_RTX, VOIDmode, 0);
    mode = insn_data[icode].operand[op].mode;
! 
!   /* We need to test if the operand must be an immediate.  */
!   if (insn_data[icode].operand[op].predicate == immediate_operand)
!     {
!       if (TREE_CODE (arg) != INTEGER_CST)
! 	{
! 	  error ("argument must be a constant in the range %d to %d", min, max);
! 	  return const0_rtx;
! 	}
! 
!       if (min >= 0) /* Unsigned number */
! 	{
! 	  if (TREE_INT_CST_LOW (arg) < (unsigned HOST_WIDE_INT) min || 
! 	      TREE_INT_CST_LOW (arg) > (unsigned HOST_WIDE_INT) max)
! 	    {
! 		
! 	      error ("argument must be a constant in the range %d to %d", min,
! 		     max);
! 	      return const0_rtx;
! 	    }
! 	}
!       else /* Signed number */
! 	{
! 	  if (TREE_INT_CST_LOW (arg) + (unsigned HOST_WIDE_INT) (-min) >
! 	      (unsigned HOST_WIDE_INT)(max - min))
! 	    {
! 		
! 	      error ("argument must be a constant in the range %d to %d", min,
! 		     max);
! 	      return const0_rtx;
! 	    }
! 	}
!     }
!   else if (!insn_data[icode].operand[op].predicate (value, mode))
      value = copy_to_mode_reg (mode, value);
  
    *arglist = TREE_CHAIN (*arglist);
*************** mips_expand_builtin (tree exp, rtx targe
*** 9772,9778 ****
    switch (type)
      {
      case MIPS_BUILTIN_DIRECT:
!       return mips_expand_builtin_direct (icode, target, arglist);
  
      case MIPS_BUILTIN_MOVT:
      case MIPS_BUILTIN_MOVF:
--- 10087,10123 ----
    switch (type)
      {
      case MIPS_BUILTIN_DIRECT:
!       return mips_expand_builtin_direct (icode, target, arglist, 1, 0, 0);
! 
!     case MIPS_BUILTIN_DIRECT_IMM0_7:
!       return mips_expand_builtin_direct (icode, target, arglist, 1, 0, 7);
! 
!     case MIPS_BUILTIN_DIRECT_IMM0_15:
!       return mips_expand_builtin_direct (icode, target, arglist, 1, 0, 15);
! 
!     case MIPS_BUILTIN_DIRECT_IMM0_31:
!       return mips_expand_builtin_direct (icode, target, arglist, 1, 0, 31);
! 
!     case MIPS_BUILTIN_DIRECT_IMM1_32:
!       return mips_expand_builtin_direct (icode, target, arglist, 1, 1, 32);
! 
!     case MIPS_BUILTIN_DIRECT_IMM0_63:
!       return mips_expand_builtin_direct (icode, target, arglist, 1, 0, 63);
! 
!     case MIPS_BUILTIN_DIRECT_IMMn32_31:
!       return mips_expand_builtin_direct (icode, target, arglist, 1, -32, 31);
! 
!     case MIPS_BUILTIN_DIRECT_IMM0_255:
!       return mips_expand_builtin_direct (icode, target, arglist, 1, 0, 255);
! 
!     case MIPS_BUILTIN_DIRECT_IMM0_1023:
!       return mips_expand_builtin_direct (icode, target, arglist, 1, 0, 1023);
! 
!     case MIPS_BUILTIN_DIRECT_NO_TARGET:
!       return mips_expand_builtin_direct (icode, target, arglist, 0, 0, 0);
! 
!     case MIPS_BUILTIN_DIRECT_NO_TARGET_IMM0_63:
!       return mips_expand_builtin_direct (icode, target, arglist, 0, 0, 63);
  
      case MIPS_BUILTIN_MOVT:
      case MIPS_BUILTIN_MOVF:
*************** mips_expand_builtin (tree exp, rtx targe
*** 9787,9792 ****
--- 10132,10140 ----
        return mips_expand_builtin_compare (type, icode, bdesc[fcode].cond,
  					  target, arglist);
  
+     case MIPS_BUILTIN_BPOSGE32:
+       return mips_expand_builtin_bposge (type, target);
+ 
      default:
        return 0;
      }
*************** mips_init_builtins (void)
*** 9801,9870 ****
    const struct bdesc_map *m;
    tree types[(int) MIPS_MAX_FTYPE_MAX];
    tree V2SF_type_node;
    unsigned int offset;
  
!   /* We have only builtins for -mpaired-single and -mips3d.  */
!   if (!TARGET_PAIRED_SINGLE_FLOAT)
      return;
  
!   V2SF_type_node = build_vector_type_for_mode (float_type_node, V2SFmode);
  
!   types[MIPS_V2SF_FTYPE_V2SF]
!     = build_function_type_list (V2SF_type_node, V2SF_type_node, NULL_TREE);
  
!   types[MIPS_V2SF_FTYPE_V2SF_V2SF]
!     = build_function_type_list (V2SF_type_node,
! 				V2SF_type_node, V2SF_type_node, NULL_TREE);
! 
!   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);
! 
!   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);
! 
!   types[MIPS_V2SF_FTYPE_SF_SF]
!     = build_function_type_list (V2SF_type_node,
! 				float_type_node, float_type_node, NULL_TREE);
! 
!   types[MIPS_INT_FTYPE_V2SF_V2SF]
!     = build_function_type_list (integer_type_node,
! 				V2SF_type_node, V2SF_type_node, NULL_TREE);
! 
!   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);
! 
!   types[MIPS_INT_FTYPE_SF_SF]
!     = build_function_type_list (integer_type_node,
! 				float_type_node, float_type_node, NULL_TREE);
! 
!   types[MIPS_INT_FTYPE_DF_DF]
!     = build_function_type_list (integer_type_node,
! 				double_type_node, double_type_node, NULL_TREE);
! 
!   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);
  
    /* Iterate through all of the bdesc arrays, initializing all of the
       builtin functions.  */
--- 10149,10362 ----
    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;
  
!   if (TARGET_PAIRED_SINGLE_FLOAT)
!     {
!       V2SF_type_node = build_vector_type_for_mode (float_type_node, V2SFmode);
  
!       types[MIPS_V2SF_FTYPE_V2SF]
! 	= build_function_type_list (V2SF_type_node, V2SF_type_node, NULL_TREE);
! 	
!       types[MIPS_V2SF_FTYPE_V2SF_V2SF]
! 	= build_function_type_list (V2SF_type_node,
! 				    V2SF_type_node, V2SF_type_node, NULL_TREE);
! 
!       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);
! 
!       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);
! 
!       types[MIPS_V2SF_FTYPE_SF_SF]
! 	= build_function_type_list (V2SF_type_node,
! 				    float_type_node, float_type_node, NULL_TREE);
! 
!       types[MIPS_INT_FTYPE_V2SF_V2SF]
! 	= build_function_type_list (integer_type_node,
! 				    V2SF_type_node, V2SF_type_node, NULL_TREE);
! 
!       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);
! 
!       types[MIPS_INT_FTYPE_SF_SF]
! 	= build_function_type_list (integer_type_node,
! 				    float_type_node, float_type_node, NULL_TREE);
! 
!       types[MIPS_INT_FTYPE_DF_DF]
! 	= build_function_type_list (integer_type_node,
! 				    double_type_node, double_type_node, NULL_TREE);
! 
!       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.  */
*************** mips_init_builtins (void)
*** 9884,9918 ****
  
  /* 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.  */
  
  static rtx
! mips_expand_builtin_direct (enum insn_code icode, rtx target, tree arglist)
  {
    rtx ops[MAX_RECOG_OPERANDS];
    int i;
  
!   target = mips_prepare_builtin_target (icode, 0, target);
!   for (i = 1; i < insn_data[icode].n_operands; i++)
!     ops[i] = mips_prepare_builtin_arg (icode, i, &arglist);
! 
!   switch (insn_data[icode].n_operands)
      {
!     case 2:
!       emit_insn (GEN_FCN (icode) (target, ops[1]));
!       break;
  
!     case 3:
!       emit_insn (GEN_FCN (icode) (target, ops[1], ops[2]));
!       break;
  
!     case 4:
!       emit_insn (GEN_FCN (icode) (target, ops[1], ops[2], ops[3]));
!       break;
  
!     default:
!       gcc_unreachable ();
      }
    return target;
  }
  
--- 10376,10435 ----
  
  /* 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.
!    MIN and MAX are only used as a range when the last operand must be a
!    constant.  */
  
  static rtx
! mips_expand_builtin_direct (enum insn_code icode, rtx target, tree arglist,
! 			    int has_target, int min, int max)
  {
    rtx ops[MAX_RECOG_OPERANDS];
    int i;
  
!   if (has_target)
      {
!       target = mips_prepare_builtin_target (icode, 0, target);
!       /* We need to test if arglist is not zero.  Some instructions have extra 
! 	 clobber registers.  */
!       for (i = 1; i < insn_data[icode].n_operands && arglist != 0; i++)
! 	ops[i] = mips_prepare_builtin_arg (icode, i, &arglist, min, max);
  
!       switch (i)
! 	{
! 	case 2:
! 	  emit_insn (GEN_FCN (icode) (target, ops[1]));
! 	  break;
  
! 	case 3:
! 	  emit_insn (GEN_FCN (icode) (target, ops[1], ops[2]));
! 	  break;
  
! 	case 4:
! 	  emit_insn (GEN_FCN (icode) (target, ops[1], ops[2], ops[3]));
! 	  break;
! 
! 	default:
! 	  gcc_unreachable ();
! 	}
!     }
!   else /* no target */
!     {
!       for (i = 0; i < insn_data[icode].n_operands && arglist != 0; i++)
! 	ops[i] = mips_prepare_builtin_arg (icode, i, &arglist, min, max);
! 
!       switch (i)
! 	{
! 	case 2:
! 	  emit_insn (GEN_FCN (icode) (ops[0], ops[1]));
! 	  break;
! 
! 	default:
! 	  gcc_unreachable ();
! 	}
      }
+ 
    return target;
  }
  
*************** mips_expand_builtin_movtf (enum mips_bui
*** 9930,9950 ****
    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;
--- 10447,10467 ----
    rtx cmp_result, op0, op1;
  
    cmp_result = mips_prepare_builtin_target (icode, 0, 0);
!   op0 = mips_prepare_builtin_arg (icode, 1, &arglist, 0, 0);
!   op1 = mips_prepare_builtin_arg (icode, 2, &arglist, 0, 0);
    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, 0, 0);
!       op0 = mips_prepare_builtin_arg (icode, 1, &arglist, 0, 0);
      }
    else
      {
!       op0 = mips_prepare_builtin_arg (icode, 1, &arglist, 0, 0);
!       op1 = mips_prepare_builtin_arg (icode, 2, &arglist, 0, 0);
      }
    emit_insn (gen_mips_cond_move_tf_ps (target, op0, op1, cmp_result));
    return target;
*************** mips_expand_builtin_compare (enum mips_b
*** 9971,9977 ****
    /* 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);
  
    switch (insn_data[icode].n_operands)
      {
--- 10488,10494 ----
    /* 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, 0, 0);
  
    switch (insn_data[icode].n_operands)
      {
*************** mips_expand_builtin_compare (enum mips_b
*** 10037,10041 ****
--- 10554,10611 ----
  
    return target;
  }
+ 
+ /* Expand a bposge builtin of type BUILTIN_TYPE.
+    TARGET, if nonnull, suggests a good place to put the boolean result.
+    Ex:
+ 	move		target, 0
+ 	bposge32	label1
+ 	j		label2
+    label1:
+ 	move 		target, 1
+    label2: 
+ 	...  */
+ 
+ static rtx
+ mips_expand_builtin_bposge (enum mips_builtin_type builtin_type, rtx target)
+ {
+   rtx label1, label2, if_then_else;
+   rtx cmp_result;
+   int cmp_value;
+ 
+   if (target == 0 || GET_MODE (target) != SImode)
+     target = gen_reg_rtx (SImode);
+ 
+   cmp_result = gen_rtx_REG (CCDSPmode, DSP_CONTROL_PO_REGNUM);
+ 
+   if (builtin_type == MIPS_BUILTIN_BPOSGE32)
+     cmp_value = 32;
+   else
+     gcc_assert (0);
+ 
+   /* Move 0 to target */
+   emit_move_insn (target, const0_rtx);
+ 
+   /* Generate two labels */
+   label1 = gen_label_rtx ();
+   label2 = gen_label_rtx ();
+ 
+   /* Generate if_then_else */
+   if_then_else
+     = gen_rtx_IF_THEN_ELSE (VOIDmode,
+ 			    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_barrier ();
+   emit_label (label1);
+   emit_move_insn (target, const1_rtx);
+   emit_label (label2);
+ 
+   return target;
+ }
  
  #include "gt-mips.h"
Index: config/mips/mips.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/mips/mips.h,v
retrieving revision 1.393
diff -c -3 -p -r1.393 mips.h
*** config/mips/mips.h	13 May 2005 15:24:34 -0000	1.393
--- config/mips/mips.h	24 May 2005 22:41:18 -0000
*************** extern const struct mips_cpu_info *mips_
*** 1120,1128 ****
  	- ARG_POINTER_REGNUM
  	- FRAME_POINTER_REGNUM
  	- FAKE_CALL_REGNO (see the comment above load_callsi for details)
!    - 3 dummy entries that were used at various times in the past.  */
  
! #define FIRST_PSEUDO_REGISTER 176
  
  /* By default, fix the kernel registers ($26 and $27), the global
     pointer ($28) and the stack pointer ($29).  This can change
--- 1120,1130 ----
  	- ARG_POINTER_REGNUM
  	- FRAME_POINTER_REGNUM
  	- FAKE_CALL_REGNO (see the comment above load_callsi for details)
!    - 3 dummy entries that were used at various times in the past.
!    - 6 DSP accumulator registers (3 hi-lo pairs) for MIPS DSP ASE
!    - 6 DSP control register  */
  
! #define FIRST_PSEUDO_REGISTER 188
  
  /* By default, fix the kernel registers ($26 and $27), the global
     pointer ($28) and the stack pointer ($29).  This can change
*************** extern const struct mips_cpu_info *mips_
*** 1149,1155 ****
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,			\
    /* COP3 registers */							\
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,			\
!   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1			\
  }
  
  
--- 1151,1159 ----
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,			\
    /* COP3 registers */							\
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,			\
!   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,			\
!   /* 6 DSP accumulator registers & 6 control registers */		\
!   0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1					\
  }
  
  
*************** extern const struct mips_cpu_info *mips_
*** 1179,1185 ****
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,			\
    /* COP3 registers */							\
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,			\
!   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1			\
  }
  
  
--- 1183,1191 ----
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,			\
    /* COP3 registers */							\
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,			\
!   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,			\
!   /* 6 DSP accumulator registers & 6 control registers */		\
!   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1					\
  }
  
  
*************** extern const struct mips_cpu_info *mips_
*** 1202,1208 ****
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,			\
    /* COP3 registers */							\
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,			\
!   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0			\
  }
  
  /* Internal macros to classify a register number as to whether it's a
--- 1208,1216 ----
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,			\
    /* COP3 registers */							\
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,			\
!   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,			\
!   /* 6 DSP accumulator registers & 6 control registers */		\
!   1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0					\
  }
  
  /* Internal macros to classify a register number as to whether it's a
*************** extern const struct mips_cpu_info *mips_
*** 1244,1249 ****
--- 1252,1268 ----
  /* ALL_COP_REG_NUM assumes that COP0,2,and 3 are numbered consecutively.  */
  #define ALL_COP_REG_NUM (COP3_REG_LAST - COP0_REG_FIRST + 1)
  
+ #define DSP_ACC_REG_FIRST 176
+ #define DSP_ACC_REG_LAST 181
+ #define DSP_ACC_REG_NUM (DSP_ACC_REG_LAST - DSP_ACC_REG_FIRST + 1)
+ 
+ #define DSP_CONTROL_PO_REGNUM 182
+ #define DSP_CONTROL_SC_REGNUM 183
+ #define DSP_CONTROL_CA_REGNUM 184
+ #define DSP_CONTROL_OU_REGNUM 185
+ #define DSP_CONTROL_CC_REGNUM 186
+ #define DSP_CONTROL_EF_REGNUM 187
+ 
  #define AT_REGNUM	(GP_REG_FIRST + 1)
  #define HI_REGNUM	(MD_REG_FIRST + 0)
  #define LO_REGNUM	(MD_REG_FIRST + 1)
*************** extern const struct mips_cpu_info *mips_
*** 1271,1276 ****
--- 1290,1297 ----
    ((unsigned int) ((int) (REGNO) - COP3_REG_FIRST) < COP3_REG_NUM)
  #define ALL_COP_REG_P(REGNO) \
    ((unsigned int) ((int) (REGNO) - COP0_REG_FIRST) < ALL_COP_REG_NUM)
+ #define DSP_ACC_REG_P(REGNO) \
+   ((unsigned int) ((int) (REGNO) - DSP_ACC_REG_FIRST) < DSP_ACC_REG_NUM)
  
  #define FP_REG_RTX_P(X) (REG_P (X) && FP_REG_P (REGNO (X)))
  
*************** enum reg_class
*** 1413,1418 ****
--- 1434,1442 ----
    ALL_COP_REGS,
    ALL_COP_AND_GR_REGS,
    ST_REGS,			/* status registers (fp status) */
+   DSP_ACC_REGS,			/* DSP accumulator registers */
+   MD_AND_DSP_ACC_REGS,		/* Hi/Lo and DSP accumulator registers */
+   DSP_CNTL_REGS,		/* DSP control registers */
    ALL_REGS,			/* all registers */
    LIM_REG_CLASSES		/* max value + 1 */
  };
*************** enum reg_class
*** 1453,1458 ****
--- 1477,1485 ----
    "ALL_COP_REGS",							\
    "ALL_COP_AND_GR_REGS",						\
    "ST_REGS",								\
+   "DSP_ACC_REGS",							\
+   "MD_AND_DSP_ACC_REGS",						\
+   "DSP_CONTROL_REGS",							\
    "ALL_REGS"								\
  }
  
*************** enum reg_class
*** 1494,1499 ****
--- 1521,1529 ----
    { 0x00000000, 0x00000000, 0xffff0000, 0xffffffff, 0xffffffff, 0x0000ffff },                           \
    { 0xffffffff, 0x00000000, 0xffff0000, 0xffffffff, 0xffffffff, 0x0000ffff },                           \
    { 0x00000000, 0x00000000, 0x000007f8, 0x00000000, 0x00000000, 0x00000000 },	/* status registers */	\
+   { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x003f0000 },	/* dsp accumulator registers */	\
+   { 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x003f0000 },	/* hi/lo and dsp accumulator registers */	\
+   { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0fc00000 },	/* dsp control registers */	\
    { 0xffffffff, 0xffffffff, 0xffff07ff, 0xffffffff, 0xffffffff, 0x0000ffff }	/* all registers */	\
  }
  
*************** extern const enum reg_class mips_regno_t
*** 1555,1561 ****
    112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,	\
    128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,	\
    144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,	\
!   160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175	\
  }
  
  /* ORDER_REGS_FOR_LOCAL_ALLOC is a macro which permits reg_alloc_order
--- 1585,1592 ----
    112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,	\
    128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,	\
    144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,	\
!   160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,	\
!   176,177,178,179,180,181,182,183,184,185,186,187			\
  }
  
  /* ORDER_REGS_FOR_LOCAL_ALLOC is a macro which permits reg_alloc_order
*************** extern const enum reg_class mips_regno_t
*** 1586,1591 ****
--- 1617,1623 ----
     'B'  Cop0 register
     'C'  Cop2 register
     'D'  Cop3 register
+    'a'  MD registers and DSP accumulator registers
     'b'	All registers */
  
  extern enum reg_class mips_char_to_class[256];
*************** typedef struct mips_args {
*** 2361,2367 ****
    "$c3r0", "$c3r1", "$c3r2", "$c3r3", "$c3r4", "$c3r5", "$c3r6", "$c3r7",  \
    "$c3r8", "$c3r9", "$c3r10","$c3r11","$c3r12","$c3r13","$c3r14","$c3r15", \
    "$c3r16","$c3r17","$c3r18","$c3r19","$c3r20","$c3r21","$c3r22","$c3r23", \
!   "$c3r24","$c3r25","$c3r26","$c3r27","$c3r28","$c3r29","$c3r30","$c3r31" }
  
  /* List the "software" names for each register.  Also list the numerical
     names for $fp and $sp.  */
--- 2393,2401 ----
    "$c3r0", "$c3r1", "$c3r2", "$c3r3", "$c3r4", "$c3r5", "$c3r6", "$c3r7",  \
    "$c3r8", "$c3r9", "$c3r10","$c3r11","$c3r12","$c3r13","$c3r14","$c3r15", \
    "$c3r16","$c3r17","$c3r18","$c3r19","$c3r20","$c3r21","$c3r22","$c3r23", \
!   "$c3r24","$c3r25","$c3r26","$c3r27","$c3r28","$c3r29","$c3r30","$c3r31", \
!   "$ac1hi","$ac1lo","$ac2hi","$ac2lo","$ac3hi","$ac3lo","$dsp_po","$dsp_sc", \
!   "$dsp_ca","$dsp_ou","$dsp_cc","$dsp_ef" }
  
  /* List the "software" names for each register.  Also list the numerical
     names for $fp and $sp.  */
Index: config/mips/mips.md
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/mips/mips.md,v
retrieving revision 1.319
diff -c -3 -p -r1.319 mips.md
*** config/mips/mips.md	13 May 2005 15:24:35 -0000	1.319
--- config/mips/mips.md	24 May 2005 22:41:19 -0000
***************
*** 72,77 ****
--- 72,184 ----
     (UNSPEC_RSQRT2		209)
     (UNSPEC_RECIP1		210)
     (UNSPEC_RECIP2		211)
+ 
+    ;; MIPS DSP ASE Revision 0.976 1/25/2005
+    (UNSPEC_ADDQ_PH		300)
+    (UNSPEC_ADDQ_S_PH		301)
+    (UNSPEC_ADDQ_S_W		302)
+    (UNSPEC_ADDU_QB		303)
+    (UNSPEC_ADDU_S_QB		304)
+    (UNSPEC_SUBQ_PH		305)
+    (UNSPEC_SUBQ_S_PH		306)
+    (UNSPEC_SUBQ_S_W		307)
+    (UNSPEC_SUBU_QB		308)
+    (UNSPEC_SUBU_S_QB		309)
+    (UNSPEC_ADDSC		310)
+    (UNSPEC_ADDWC		311)
+    (UNSPEC_MODSUB		312)
+    (UNSPEC_RADDU_W_QB		313)
+    (UNSPEC_ABSQ_PH		314)
+    (UNSPEC_ABSQ_S_PH		315)
+    (UNSPEC_ABSQ_S_W		316)
+    (UNSPEC_PRECRQ_QB_PH		317)
+    (UNSPEC_PRECRQ_PH_W		318)
+    (UNSPEC_PRECRQ_RS_PH_W	319)
+    (UNSPEC_PRECRQU_S_QB_PH	320)
+    (UNSPEC_PRECEQ_W_PHL		321)
+    (UNSPEC_PRECEQ_W_PHR		322)
+    (UNSPEC_PRECEQU_PH_QBL	323)
+    (UNSPEC_PRECEQU_PH_QBR	324)
+    (UNSPEC_PRECEQU_PH_QBLA	325)
+    (UNSPEC_PRECEQU_PH_QBRA	326)
+    (UNSPEC_PRECEU_PH_QBL	327)
+    (UNSPEC_PRECEU_PH_QBR	328)
+    (UNSPEC_PRECEU_PH_QBLA	329)
+    (UNSPEC_PRECEU_PH_QBRA	330)
+    (UNSPEC_SHLL_QB		331)
+    (UNSPEC_SHLLV_QB		332)
+    (UNSPEC_SHLL_PH		333)
+    (UNSPEC_SHLLV_PH		334)
+    (UNSPEC_SHLL_S_PH		335)
+    (UNSPEC_SHLLV_S_PH		336)
+    (UNSPEC_SHLL_S_W		337)
+    (UNSPEC_SHLLV_S_W		338)
+    (UNSPEC_SHRL_QB		339)
+    (UNSPEC_SHRLV_QB		340)
+    (UNSPEC_SHRA_PH		341)
+    (UNSPEC_SHRAV_PH		342)
+    (UNSPEC_SHRA_R_PH		343)
+    (UNSPEC_SHRAV_R_PH		344)
+    (UNSPEC_SHRA_R_W		345)
+    (UNSPEC_SHRAV_R_W		346)
+    (UNSPEC_MULEU_S_PH_QBL	347)
+    (UNSPEC_MULEU_S_PH_QBR	348)
+    (UNSPEC_MULQ_RS_PH		349)
+    (UNSPEC_MULEQ_S_W_PHL	350)
+    (UNSPEC_MULEQ_S_W_PHR	351)
+    (UNSPEC_DPAU_H_QBL		352)
+    (UNSPEC_DPAU_H_QBR		353)
+    (UNSPEC_DPSU_H_QBL		354)
+    (UNSPEC_DPSU_H_QBR		355)
+    (UNSPEC_DPAQ_S_W_PH		356)
+    (UNSPEC_DPSQ_S_W_PH		357)
+    (UNSPEC_MULSAQ_S_W_PH	358)
+    (UNSPEC_DPAQ_SA_L_W		359)
+    (UNSPEC_DPSQ_SA_L_W		360)
+    (UNSPEC_MAQ_S_W_PHL		361)
+    (UNSPEC_MAQ_S_W_PHR		362)
+    (UNSPEC_MAQ_SA_W_PHL		363)
+    (UNSPEC_MAQ_SA_W_PHR		364)
+    (UNSPEC_BITREV		365)
+    (UNSPEC_INSV			366)
+    (UNSPEC_REPL_QB		367)
+    (UNSPEC_REPLV_QB		368)
+    (UNSPEC_REPL_PH		369)
+    (UNSPEC_REPLV_PH		370)
+    (UNSPEC_CMPU_EQ_QB		371)
+    (UNSPEC_CMPU_LT_QB		372)
+    (UNSPEC_CMPU_LE_QB		373)
+    (UNSPEC_CMPGU_EQ_QB		374)
+    (UNSPEC_CMPGU_LT_QB		375)
+    (UNSPEC_CMPGU_LE_QB		376)
+    (UNSPEC_CMP_EQ_PH		377)
+    (UNSPEC_CMP_LT_PH		378)
+    (UNSPEC_CMP_LE_PH		379)
+    (UNSPEC_PICK_QB		380)
+    (UNSPEC_PICK_PH		381)
+    (UNSPEC_PACKRL_PH		382)
+    (UNSPEC_EXTR_W		383)
+    (UNSPEC_EXTR_R_W		384)
+    (UNSPEC_EXTR_RS_W		385)
+    (UNSPEC_EXTR_S_H		386)
+    (UNSPEC_EXTRV_S_H		387)
+    (UNSPEC_EXTRV_W		388)
+    (UNSPEC_EXTRV_R_W		389)
+    (UNSPEC_EXTRV_RS_W		390)
+    (UNSPEC_EXTL_W		391)
+    (UNSPEC_EXTL_S_W		392)
+    (UNSPEC_EXTLV_W		393)
+    (UNSPEC_EXTLV_S_W		394)
+    (UNSPEC_EXTP			395)
+    (UNSPEC_EXTPV		396)
+    (UNSPEC_EXTPDP		397)
+    (UNSPEC_EXTPDPV		398)
+    (UNSPEC_SHILO		399)
+    (UNSPEC_SHILOV		400)
+    (UNSPEC_MTHLIP		401)
+    (UNSPEC_WRDSP		402)
+    (UNSPEC_RDDSP		403)
+ 
    ]
  )
  
*************** beq\t%2,%.,1b\;\
*** 3117,3124 ****
     (set_attr "mode" "<MODE>")])
  
  (define_insn "*movdi_32bit"
!   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
! 	(match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
    "!TARGET_64BIT && !TARGET_MIPS16
     && (register_operand (operands[0], DImode)
         || reg_or_0_operand (operands[1], DImode))"
--- 3224,3231 ----
     (set_attr "mode" "<MODE>")])
  
  (define_insn "*movdi_32bit"
!   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x*a,*d,*B*C*D,*B*C*D,*d,*m")
! 	(match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x*a,*d,*m,*B*C*D,*B*C*D"))]
    "!TARGET_64BIT && !TARGET_MIPS16
     && (register_operand (operands[0], DImode)
         || reg_or_0_operand (operands[1], DImode))"
*************** beq\t%2,%.,1b\;\
*** 3235,3249 ****
  ;; in FP registers (off by default, use -mdebugh to enable).
  
  (define_insn "*movsi_internal"
!   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*B*C*D,*B*C*D,*d,*m")
! 	(match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,*J*d,*d,*m,*B*C*D,*B*C*D"))]
    "!TARGET_MIPS16
     && (register_operand (operands[0], SImode)
         || reg_or_0_operand (operands[1], SImode))"
    { return mips_output_move (operands[0], operands[1]); }
!   [(set_attr "type"	"arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
     (set_attr "mode"	"SI")
!    (set_attr "length"	"4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
  
  (define_insn "*movsi_mips16"
    [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
--- 3342,3356 ----
  ;; in FP registers (off by default, use -mdebugh to enable).
  
  (define_insn "*movsi_internal"
!   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x*a,*d,*B*C*D,*B*C*D,*d,*m")
! 	(match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,*J*d,*x*a,*d,*m,*B*C*D,*B*C*D"))]
    "!TARGET_MIPS16
     && (register_operand (operands[0], SImode)
         || reg_or_0_operand (operands[1], SImode))"
    { return mips_output_move (operands[0], operands[1]); }
!   [(set_attr "type"	"arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,mfhilo,xfer,load,xfer,store")
     (set_attr "mode"	"SI")
!    (set_attr "length"	"4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,*,4,*")])
  
  (define_insn "*movsi_mips16"
    [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
*************** beq\t%2,%.,1b\;\
*** 5346,5348 ****
--- 5453,5459 ----
  ; The MIPS Paired-Single Floating Point and MIPS-3D Instructions.
  
  (include "mips-ps-3d.md")
+ 
+ ; The MIPS DSP Instructions.
+ 
+ (include "mips-dsp.md")
Index: config/mips/mips.opt
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/mips/mips.opt,v
retrieving revision 1.4
diff -c -3 -p -r1.4 mips.opt
*** config/mips/mips.opt	6 May 2005 23:41:07 -0000	1.4
--- config/mips/mips.opt	24 May 2005 22:41:19 -0000
*************** mdouble-float
*** 55,60 ****
--- 55,64 ----
  Target Report RejectNegative InverseMask(SINGLE_FLOAT, DOUBLE_FLOAT)
  Allow hardware floating-point instructions to cover both 32-bit and 64-bit operations
  
+ mdsp
+ Target Report RejectNegative Mask(DSP)
+ Use MIPS-DSP instructions
+ 
  mdebug
  Target Var(TARGET_DEBUG_MODE) Undocumented
  
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mips-dsp.md
Type: application/octet-stream
Size: 46357 bytes
Desc: mips-dsp.md
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20050524/c11d22e6/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mips32-dsp.c
Type: application/octet-stream
Size: 24363 bytes
Desc: mips32-dsp.c
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20050524/c11d22e6/attachment-0001.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mips32-dsp-type.c
Type: application/octet-stream
Size: 600 bytes
Desc: mips32-dsp-type.c
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20050524/c11d22e6/attachment-0002.obj>


More information about the Gcc-patches mailing list