diff mbox

[MIPS,GCC4.8] add MIPS64DSPR2 support.

Message ID CAJBMM-ubZbjmDtfWAu+OYXUz59GtNhZ7mZPVn75fUQs6Rh+18w@mail.gmail.com
State New
Headers show

Commit Message

Jia Liu Feb. 3, 2012, 7:13 a.m. UTC
Hi all

I've added MIPS64DSPR2 support to gcc.
Please review.

Thanks.


gcc/
2012-02-03  Jia Liu  <proljc@gmail.com>

       * config/mips/mips-dspr2.md : add MIPS64DSPR2 insns.

       * config/mips/mips-ftypes.def : builtin type for MIPS64DSPR2 insns.

       * config/mips/mips.c: builtins for MIPS64DSPR2 insns.

       * doc/extend.texi : builtins protos for MIPS64DSPR2 insns.

gcc/testsuite/
2012-02-03  Jia Liu  <proljc@gmail.com>

       * testsuite/gcc.target/mips/mips64-dspr2.c : New test.
diff mbox

Patch

From b21e65c85d87694fb8bbc24f0db7b9e56c378fd1 Mon Sep 17 00:00:00 2001
From: Jia Liu <proljc@gmail.com>
Date: Fri, 3 Feb 2012 14:50:44 +0800
Subject: [PATCH] add MIPS64DSPR2 support
Content-Type: text/plain; charset="utf-8"

---
 gcc/config/mips/mips-dspr2.md                |  348 ++++++++++++++++++++++++++
 gcc/config/mips/mips-ftypes.def              |    6 +
 gcc/config/mips/mips.c                       |   28 ++
 gcc/doc/extend.texi                          |   24 ++
 gcc/testsuite/gcc.target/mips/mips64-dspr2.c |  197 +++++++++++++++
 5 files changed, 603 insertions(+), 0 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/mips/mips64-dspr2.c

diff --git a/gcc/config/mips/mips-dspr2.md b/gcc/config/mips/mips-dspr2.md
index 108f51b..37982bd 100644
--- a/gcc/config/mips/mips-dspr2.md
+++ b/gcc/config/mips/mips-dspr2.md
@@ -20,17 +20,29 @@ 
 
 (define_c_enum "unspec" [
   UNSPEC_ABSQ_S_QB
+  UNSPEC_ABSQ_S_OB
   UNSPEC_ADDU_PH
+  UNSPEC_ADDU_QH
   UNSPEC_ADDU_S_PH
+  UNSPEC_ADDU_S_QH
   UNSPEC_ADDUH_QB
+  UNSPEC_ADDUH_OB
   UNSPEC_ADDUH_R_QB
+  UNSPEC_ADDUH_R_OB
   UNSPEC_APPEND
+  UNSPEC_DAPPEND
   UNSPEC_BALIGN
+  UNSPEC_DBALIGN
   UNSPEC_CMPGDU_EQ_QB
+  UNSPEC_CMPGDU_EQ_OB
   UNSPEC_CMPGDU_LT_QB
+  UNSPEC_CMPGDU_LT_OB
   UNSPEC_CMPGDU_LE_QB
+  UNSPEC_CMPGDU_LE_OB
   UNSPEC_DPA_W_PH
+  UNSPEC_DPA_W_QH
   UNSPEC_DPS_W_PH
+  UNSPEC_DPS_W_QH
   UNSPEC_MADD
   UNSPEC_MADDU
   UNSPEC_MSUB
@@ -44,16 +56,28 @@ 
   UNSPEC_MULT
   UNSPEC_MULTU
   UNSPEC_PRECR_QB_PH
+  UNSPEC_PRECR_OB_QH
   UNSPEC_PRECR_SRA_PH_W
+  UNSPEC_PRECR_SRA_QH_PW
   UNSPEC_PRECR_SRA_R_PH_W
+  UNSPEC_PRECR_SRA_R_QH_PW
   UNSPEC_PREPEND
+  UNSPEC_PREPENDD
+  UNSPEC_PREPENDW
   UNSPEC_SHRA_QB
   UNSPEC_SHRA_R_QB
+  UNSPEC_SHRA_OB
+  UNSPEC_SHRA_R_OB
   UNSPEC_SHRL_PH
+  UNSPEC_SHRL_QH
   UNSPEC_SUBU_PH
   UNSPEC_SUBU_S_PH
+  UNSPEC_SUBU_QH
+  UNSPEC_SUBU_S_QH
   UNSPEC_SUBUH_QB
   UNSPEC_SUBUH_R_QB
+  UNSPEC_SUBUH_OB
+  UNSPEC_SUBUH_R_OB
   UNSPEC_ADDQH_PH
   UNSPEC_ADDQH_R_PH
   UNSPEC_ADDQH_W
@@ -82,6 +106,18 @@ 
   [(set_attr "type"	"arith")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_absq_s_ob"
+  [(parallel
+    [(set (match_operand:V8QI 0 "register_operand" "=d")
+	  (unspec:V8QI [(match_operand:V8QI 1 "reg_or_0_operand" "dYG")]
+		       UNSPEC_ABSQ_S_OB))
+     (set (reg:CCDSP CCDSP_OU_REGNUM)
+	  (unspec:CCDSP [(match_dup 1)] UNSPEC_ABSQ_S_OB))])]
+  "ISA_HAS_DSPR2"
+  "absq_s.ob\t%0,%z1"
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mips_addu_ph"
   [(parallel
     [(set (match_operand:V2HI 0 "register_operand" "=d")
@@ -94,6 +130,18 @@ 
   [(set_attr "type"	"arith")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_addu_qh"
+  [(parallel
+    [(set (match_operand:V4HI 0 "register_operand" "=d")
+	  (plus:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "dYG")
+		     (match_operand:V4HI 2 "reg_or_0_operand" "dYG")))
+     (set (reg:CCDSP CCDSP_OU_REGNUM)
+	  (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_ADDU_QH))])]
+  "ISA_HAS_DSPR2"
+  "addu.qh\t%0,%z1,%z2"
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mips_addu_s_ph"
   [(parallel
     [(set (match_operand:V2HI 0 "register_operand" "=d")
@@ -107,6 +155,19 @@ 
   [(set_attr "type"	"arith")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_addu_s_qh"
+  [(parallel
+    [(set (match_operand:V4HI 0 "register_operand" "=d")
+	  (unspec:V4HI [(match_operand:V4HI 1 "reg_or_0_operand" "dYG")
+			(match_operand:V4HI 2 "reg_or_0_operand" "dYG")]
+		       UNSPEC_ADDU_S_QH))
+     (set (reg:CCDSP CCDSP_OU_REGNUM)
+	  (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_ADDU_S_QH))])]
+  "ISA_HAS_DSPR2"
+  "addu_s.qh\t%0,%z1,%z2"
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mips_adduh_qb"
   [(set (match_operand:V4QI 0 "register_operand" "=d")
 	(unspec:V4QI [(match_operand:V4QI 1 "reg_or_0_operand" "dYG")
@@ -117,6 +178,16 @@ 
   [(set_attr "type"	"arith")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_adduh_ob"
+  [(set (match_operand:V8QI 0 "register_operand" "=d")
+	(unspec:V8QI [(match_operand:V8QI 1 "reg_or_0_operand" "dYG")
+		      (match_operand:V8QI 2 "reg_or_0_operand" "dYG")]
+		     UNSPEC_ADDUH_OB))]
+  "ISA_HAS_DSPR2"
+  "adduh.ob\t%0,%z1,%z2"
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mips_adduh_r_qb"
   [(set (match_operand:V4QI 0 "register_operand" "=d")
 	(unspec:V4QI [(match_operand:V4QI 1 "reg_or_0_operand" "dYG")
@@ -127,6 +198,16 @@ 
   [(set_attr "type"	"arith")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_adduh_r_ob"
+  [(set (match_operand:V8QI 0 "register_operand" "=d")
+	(unspec:V8QI [(match_operand:V8QI 1 "reg_or_0_operand" "dYG")
+		      (match_operand:V8QI 2 "reg_or_0_operand" "dYG")]
+		     UNSPEC_ADDUH_R_OB))]
+  "ISA_HAS_DSPR2"
+  "adduh_r.ob\t%0,%z1,%z2"
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mips_append"
   [(set (match_operand:SI 0 "register_operand" "=d")
 	(unspec:SI [(match_operand:SI 1 "register_operand" "0")
@@ -142,6 +223,21 @@ 
   [(set_attr "type"	"arith")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_dappend"
+  [(set (match_operand:DI 0 "register_operand" "=d")
+	(unspec:DI [(match_operand:DI 1 "register_operand" "0")
+		    (match_operand:DI 2 "reg_or_0_operand" "dJ")
+		    (match_operand:DI 3 "const_int_operand" "n")]
+		   UNSPEC_DAPPEND))]
+  "ISA_HAS_DSPR2"
+{
+  if (INTVAL (operands[3]) & ~(unsigned HOST_WIDE_INT) 31)
+    operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
+  return "dappend\t%0,%z2,%3";
+}
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mips_balign"
   [(set (match_operand:SI 0 "register_operand" "=d")
 	(unspec:SI [(match_operand:SI 1 "register_operand" "0")
@@ -157,6 +253,21 @@ 
   [(set_attr "type"	"arith")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_dbalign"
+  [(set (match_operand:DI 0 "register_operand" "=d")
+	(unspec:DI [(match_operand:DI 1 "register_operand" "0")
+		    (match_operand:DI 2 "reg_or_0_operand" "dJ")
+		    (match_operand:DI 3 "const_int_operand" "n")]
+		   UNSPEC_DBALIGN))]
+  "ISA_HAS_DSPR2"
+{
+  if (INTVAL (operands[3]) & ~(unsigned HOST_WIDE_INT) 3)
+    operands[2] = GEN_INT (INTVAL (operands[2]) & 3);
+  return "dbalign\t%0,%z2,%3";
+}
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mips_cmpgdu_eq_qb"
   [(parallel
     [(set (match_operand:SI 0 "register_operand" "=d")
@@ -172,6 +283,21 @@ 
   [(set_attr "type"	"arith")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_cmpgdu_eq_ob"
+  [(parallel
+    [(set (match_operand:DI 0 "register_operand" "=d")
+	  (unspec:DI [(match_operand:V8QI 1 "reg_or_0_operand" "dYG")
+		      (match_operand:V8QI 2 "reg_or_0_operand" "dYG")]
+		     UNSPEC_CMPGDU_EQ_OB))
+     (set (reg:CCDSP CCDSP_CC_REGNUM)
+	  (unspec:CCDSP [(match_dup 1) (match_dup 2)
+			 (reg:CCDSP CCDSP_CC_REGNUM)]
+			UNSPEC_CMPGDU_EQ_OB))])]
+  "ISA_HAS_DSPR2"
+  "cmpgdu.eq.ob\t%0,%z1,%z2"
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mips_cmpgdu_lt_qb"
   [(parallel
     [(set (match_operand:SI 0 "register_operand" "=d")
@@ -187,6 +313,21 @@ 
   [(set_attr "type"	"arith")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_cmpgdu_lt_ob"
+  [(parallel
+    [(set (match_operand:DI 0 "register_operand" "=d")
+	  (unspec:DI [(match_operand:V8QI 1 "reg_or_0_operand" "dYG")
+		      (match_operand:V8QI 2 "reg_or_0_operand" "dYG")]
+		     UNSPEC_CMPGDU_LT_OB))
+     (set (reg:CCDSP CCDSP_CC_REGNUM)
+	  (unspec:CCDSP [(match_dup 1) (match_dup 2)
+			 (reg:CCDSP CCDSP_CC_REGNUM)]
+			UNSPEC_CMPGDU_LT_OB))])]
+  "ISA_HAS_DSPR2"
+  "cmpgdu.lt.ob\t%0,%z1,%z2"
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mips_cmpgdu_le_qb"
   [(parallel
     [(set (match_operand:SI 0 "register_operand" "=d")
@@ -202,6 +343,21 @@ 
   [(set_attr "type"	"arith")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_cmpgdu_le_ob"
+  [(parallel
+    [(set (match_operand:DI 0 "register_operand" "=d")
+	  (unspec:DI [(match_operand:V8QI 1 "reg_or_0_operand" "dYG")
+		      (match_operand:V8QI 2 "reg_or_0_operand" "dYG")]
+		     UNSPEC_CMPGDU_LE_OB))
+     (set (reg:CCDSP CCDSP_CC_REGNUM)
+	  (unspec:CCDSP [(match_dup 1) (match_dup 2)
+			 (reg:CCDSP CCDSP_CC_REGNUM)]
+			UNSPEC_CMPGDU_LE_OB))])]
+  "ISA_HAS_DSPR2"
+  "cmpgdu.le.ob\t%0,%z1,%z2"
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mips_dpa_w_ph"
   [(set (match_operand:DI 0 "register_operand" "=a")
 	(unspec:DI [(match_operand:DI 1 "register_operand" "0")
@@ -213,6 +369,17 @@ 
   [(set_attr "type"	"imadd")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_dpa_w_qh"
+  [(set (match_operand:TI 0 "register_operand" "=a")
+	(unspec:TI [(match_operand:TI 1 "register_operand" "0")
+		    (match_operand:V4HI 2 "reg_or_0_operand" "dYG")
+		    (match_operand:V4HI 3 "reg_or_0_operand" "dYG")]
+		   UNSPEC_DPA_W_QH))]
+  "ISA_HAS_DSPR2 && TARGET_64BIT"
+  "dpa.w.qh\t%q0,%z2,%z3"
+  [(set_attr "type"	"imadd")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mips_dps_w_ph"
   [(set (match_operand:DI 0 "register_operand" "=a")
 	(unspec:DI [(match_operand:DI 1 "register_operand" "0")
@@ -224,6 +391,17 @@ 
   [(set_attr "type"	"imadd")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_dps_w_qh"
+  [(set (match_operand:TI 0 "register_operand" "=a")
+	(unspec:TI [(match_operand:TI 1 "register_operand" "0")
+		    (match_operand:V4HI 2 "reg_or_0_operand" "dYG")
+		    (match_operand:V4HI 3 "reg_or_0_operand" "dYG")]
+		   UNSPEC_DPS_W_QH))]
+  "ISA_HAS_DSPR2 && TARGET_64BIT"
+  "dps.w.qh\t%q0,%z2,%z3"
+  [(set_attr "type"	"imadd")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mulv2hi3"
   [(parallel
     [(set (match_operand:V2HI 0 "register_operand" "=d")
@@ -314,6 +492,16 @@ 
   [(set_attr "type"	"arith")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_precr_ob_qh"
+  [(set (match_operand:V8QI 0 "register_operand" "=d")
+	(unspec:V8QI [(match_operand:V4HI 1 "reg_or_0_operand" "dYG")
+		      (match_operand:V4HI 2 "reg_or_0_operand" "dYG")]
+		     UNSPEC_PRECR_OB_QH))]
+  "ISA_HAS_DSPR2"
+  "precr.ob.qh\t%0,%z1,%z2"
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mips_precr_sra_ph_w"
   [(set (match_operand:V2HI 0 "register_operand" "=d")
 	(unspec:V2HI [(match_operand:SI 1 "register_operand" "0")
@@ -329,6 +517,21 @@ 
   [(set_attr "type"	"arith")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_precr_sra_qh_pw"
+  [(set (match_operand:V4HI 0 "register_operand" "=d")
+	(unspec:V4HI [(match_operand:V2SI 1 "register_operand" "0")
+		      (match_operand:V2SI 2 "reg_or_0_operand" "dJ")
+		      (match_operand:V2SI 3 "const_int_operand" "n")]
+		     UNSPEC_PRECR_SRA_QH_PW))]
+  "ISA_HAS_DSPR2"
+{
+  if (INTVAL (operands[3]) & ~(unsigned HOST_WIDE_INT) 31)
+    operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
+  return "precr_sra.qh.pw\t%0,%z2,%3";
+}
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mips_precr_sra_r_ph_w"
   [(set (match_operand:V2HI 0 "register_operand" "=d")
 	(unspec:V2HI [(match_operand:SI 1 "register_operand" "0")
@@ -344,6 +547,21 @@ 
   [(set_attr "type"	"arith")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_precr_sra_r_qh_pw"
+  [(set (match_operand:V4HI 0 "register_operand" "=d")
+	(unspec:V4HI [(match_operand:V2SI 1 "register_operand" "0")
+		      (match_operand:V2SI 2 "reg_or_0_operand" "dJ")
+		      (match_operand:V2SI 3 "const_int_operand" "n")]
+		     UNSPEC_PRECR_SRA_R_QH_PW))]
+  "ISA_HAS_DSPR2"
+{
+  if (INTVAL (operands[3]) & ~(unsigned HOST_WIDE_INT) 31)
+    operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
+  return "precr_sra_r.qh.pw\t%0,%z2,%3";
+}
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mips_prepend"
   [(set (match_operand:SI 0 "register_operand" "=d")
 	(unspec:SI [(match_operand:SI 1 "register_operand" "0")
@@ -359,6 +577,36 @@ 
   [(set_attr "type"	"arith")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_prependd"
+  [(set (match_operand:DI 0 "register_operand" "=d")
+	(unspec:DI [(match_operand:DI 1 "register_operand" "0")
+		    (match_operand:DI 2 "reg_or_0_operand" "dJ")
+		    (match_operand:DI 3 "const_int_operand" "n")]
+		   UNSPEC_PREPENDD))]
+  "ISA_HAS_DSPR2"
+{
+  if (INTVAL (operands[3]) & ~(unsigned HOST_WIDE_INT) 31)
+    operands[3] = GEN_INT (INTVAL (operands[3]) & 31);
+  return "prependd\t%0,%z2,%3";
+}
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")])
+
+(define_insn "mips_prependw"
+  [(set (match_operand:DI 0 "register_operand" "=d")
+	(unspec:DI [(match_operand:DI 1 "register_operand" "0")
+		    (match_operand:DI 2 "reg_or_0_operand" "dJ")
+		    (match_operand:DI 3 "const_int_operand" "n")]
+		   UNSPEC_PREPENDW))]
+  "ISA_HAS_DSPR2"
+{
+  if (INTVAL (operands[3]) & ~(unsigned HOST_WIDE_INT) 31)
+    operands[3] = GEN_INT (INTVAL (operands[3]) & 31);
+  return "prependw\t%0,%z2,%3";
+}
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mips_shra_qb"
   [(set (match_operand:V4QI 0 "register_operand" "=d,d")
 	(unspec:V4QI [(match_operand:V4QI 1 "reg_or_0_operand" "dYG,dYG")
@@ -396,6 +644,42 @@ 
   [(set_attr "type"	"shift")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_shra_ob"
+  [(set (match_operand:V8QI 0 "register_operand" "=d,d")
+	(unspec:V8QI [(match_operand:V8QI 1 "reg_or_0_operand" "dYG,dYG")
+		      (match_operand:DI 2 "arith_operand" "I,d")]
+		     UNSPEC_SHRA_OB))]
+  "ISA_HAS_DSPR2"
+{
+  if (which_alternative == 0)
+    {
+      if (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 7)
+	operands[2] = GEN_INT (INTVAL (operands[2]) & 7);
+      return "shra.ob\t%0,%z1,%2";
+    }
+  return "shrav.ob\t%0,%z1,%2";
+}
+  [(set_attr "type"	"shift")
+   (set_attr "mode"	"DI")])
+
+(define_insn "mips_shra_r_ob"
+  [(set (match_operand:V8QI 0 "register_operand" "=d,d")
+	(unspec:V8QI [(match_operand:V8QI 1 "reg_or_0_operand" "dYG,dYG")
+		      (match_operand:DI 2 "arith_operand" "I,d")]
+		     UNSPEC_SHRA_R_OB))]
+  "ISA_HAS_DSPR2"
+{
+  if (which_alternative == 0)
+    {
+      if (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 7)
+	operands[2] = GEN_INT (INTVAL (operands[2]) & 7);
+      return "shra_r.ob\t%0,%z1,%2";
+    }
+  return "shrav_r.ob\t%0,%z1,%2";
+}
+  [(set_attr "type"	"shift")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mips_shrl_ph"
   [(set (match_operand:V2HI 0 "register_operand" "=d,d")
 	(unspec:V2HI [(match_operand:V2HI 1 "reg_or_0_operand" "dYG,dYG")
@@ -414,6 +698,24 @@ 
   [(set_attr "type"	"shift")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_shrl_qh"
+  [(set (match_operand:V4HI 0 "register_operand" "=d,d")
+	(unspec:V4HI [(match_operand:V4HI 1 "reg_or_0_operand" "dYG,dYG")
+		      (match_operand:DI 2 "arith_operand" "I,d")]
+		     UNSPEC_SHRL_QH))]
+  "ISA_HAS_DSPR2"
+{
+  if (which_alternative == 0)
+    {
+      if (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 15)
+	operands[2] = GEN_INT (INTVAL (operands[2]) & 15);
+      return "shrl.qh\t%0,%z1,%2";
+    }
+  return "shrlv.qh\t%0,%z1,%2";
+}
+  [(set_attr "type"	"shift")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mips_subu_ph"
   [(parallel
     [(set (match_operand:V2HI 0 "register_operand" "=d")
@@ -440,6 +742,32 @@ 
   [(set_attr "type"	"arith")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_subu_qh"
+  [(parallel
+    [(set (match_operand:V4HI 0 "register_operand" "=d")
+	  (unspec:V4HI [(match_operand:V4HI 1 "reg_or_0_operand" "dYG")
+			(match_operand:V4HI 2 "reg_or_0_operand" "dYG")]
+		       UNSPEC_SUBU_QH))
+     (set (reg:CCDSP CCDSP_OU_REGNUM)
+	  (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_SUBU_QH))])]
+  "ISA_HAS_DSPR2"
+  "subu.qh\t%0,%z1,%z2"
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")])
+
+(define_insn "mips_subu_s_qh"
+  [(parallel
+    [(set (match_operand:V4HI 0 "register_operand" "=d")
+	  (unspec:V4HI [(match_operand:V4HI 1 "reg_or_0_operand" "dYG")
+			(match_operand:V4HI 2 "reg_or_0_operand" "dYG")]
+		       UNSPEC_SUBU_S_QH))
+     (set (reg:CCDSP CCDSP_OU_REGNUM)
+	  (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_SUBU_S_QH))])]
+  "ISA_HAS_DSPR2"
+  "subu_s.qh\t%0,%z1,%z2"
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mips_subuh_qb"
   [(set (match_operand:V4QI 0 "register_operand" "=d")
 	(unspec:V4QI [(match_operand:V4QI 1 "reg_or_0_operand" "dYG")
@@ -460,6 +788,26 @@ 
   [(set_attr "type"	"arith")
    (set_attr "mode"	"SI")])
 
+(define_insn "mips_subuh_ob"
+  [(set (match_operand:V8QI 0 "register_operand" "=d")
+	(unspec:V8QI [(match_operand:V8QI 1 "reg_or_0_operand" "dYG")
+		      (match_operand:V8QI 2 "reg_or_0_operand" "dYG")]
+		     UNSPEC_SUBUH_OB))]
+  "ISA_HAS_DSPR2"
+  "subuh.ob\t%0,%z1,%z2"
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")])
+
+(define_insn "mips_subuh_r_ob"
+  [(set (match_operand:V8QI 0 "register_operand" "=d")
+	(unspec:V8QI [(match_operand:V8QI 1 "reg_or_0_operand" "dYG")
+		      (match_operand:V8QI 2 "reg_or_0_operand" "dYG")]
+		     UNSPEC_SUBUH_R_OB))]
+  "ISA_HAS_DSPR2"
+  "subuh_r.ob\t%0,%z1,%z2"
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")])
+
 (define_insn "mips_addqh_ph"
   [(set (match_operand:V2HI 0 "register_operand" "=d")
 	(unspec:V2HI [(match_operand:V2HI 1 "reg_or_0_operand" "dYG")
diff --git a/gcc/config/mips/mips-ftypes.def b/gcc/config/mips/mips-ftypes.def
index cd1d1da..7dc1464 100644
--- a/gcc/config/mips/mips-ftypes.def
+++ b/gcc/config/mips/mips-ftypes.def
@@ -39,7 +39,13 @@  DEF_MIPS_FTYPE (2, (DF, DF, DF))
 
 DEF_MIPS_FTYPE (2, (DI, DI, DI))
 DEF_MIPS_FTYPE (2, (DI, DI, SI))
+DEF_MIPS_FTYPE (2, (DI, V8QI, V8QI))
+DEF_MIPS_FTYPE (2, (V8QI, V8QI, DI))
+DEF_MIPS_FTYPE (2, (V4HI, V4HI, DI))
 DEF_MIPS_FTYPE (3, (DI, DI, SI, SI))
+DEF_MIPS_FTYPE (3, (DI, DI, DI, DI))
+DEF_MIPS_FTYPE (3, (TI, TI, V4HI, V4HI))
+DEF_MIPS_FTYPE (3, (V4HI, V2SI, V2SI, V2SI))
 DEF_MIPS_FTYPE (3, (DI, DI, USI, USI))
 DEF_MIPS_FTYPE (3, (DI, DI, V2HI, V2HI))
 DEF_MIPS_FTYPE (3, (DI, DI, V4QI, V4QI))
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index e4231a5..c9cf4d8 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -12806,6 +12806,7 @@  AVAIL_NON_MIPS16 (dspr2, TARGET_DSPR2)
 AVAIL_NON_MIPS16 (dsp_32, !TARGET_64BIT && TARGET_DSP)
 AVAIL_NON_MIPS16 (dsp_64, TARGET_64BIT && TARGET_DSP)
 AVAIL_NON_MIPS16 (dspr2_32, !TARGET_64BIT && TARGET_DSPR2)
+AVAIL_NON_MIPS16 (dspr2_64, TARGET_64BIT && TARGET_DSPR2)
 AVAIL_NON_MIPS16 (loongson, TARGET_LOONGSON_VECTORS)
 AVAIL_NON_MIPS16 (cache, TARGET_CACHE_BUILTIN)
 
@@ -13145,6 +13146,32 @@  static const struct mips_builtin_description mips_builtins[] = {
   DIRECT_BUILTIN (dpsqx_s_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32),
   DIRECT_BUILTIN (dpsqx_sa_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32),
 
+  /* The following are for the MIPS DSP ASE REV 2 (64-bit only).  */
+  DIRECT_BUILTIN (absq_s_ob, MIPS_V8QI_FTYPE_V8QI, dspr2_64),
+  DIRECT_BUILTIN (addu_qh, MIPS_V4HI_FTYPE_V4HI_V4HI, dspr2_64),
+  DIRECT_BUILTIN (addu_s_qh, MIPS_V4HI_FTYPE_V4HI_V4HI, dspr2_64),
+  DIRECT_BUILTIN (adduh_ob, MIPS_V8QI_FTYPE_V8QI_V8QI, dspr2_64),
+  DIRECT_BUILTIN (adduh_r_ob, MIPS_V8QI_FTYPE_V8QI_V8QI, dspr2_64),
+  DIRECT_BUILTIN (dappend, MIPS_DI_FTYPE_DI_DI_DI, dspr2_64),
+  DIRECT_BUILTIN (dbalign, MIPS_DI_FTYPE_DI_DI_DI, dspr2_64),
+  DIRECT_BUILTIN (cmpgdu_eq_ob, MIPS_DI_FTYPE_V8QI_V8QI, dspr2_64),
+  DIRECT_BUILTIN (cmpgdu_lt_ob, MIPS_DI_FTYPE_V8QI_V8QI, dspr2_64),
+  DIRECT_BUILTIN (cmpgdu_le_ob, MIPS_DI_FTYPE_V8QI_V8QI, dspr2_64),
+  DIRECT_BUILTIN (dpa_w_qh, MIPS_TI_FTYPE_TI_V4HI_V4HI, dspr2_64),
+  DIRECT_BUILTIN (dps_w_qh, MIPS_TI_FTYPE_TI_V4HI_V4HI, dspr2_64),
+  DIRECT_BUILTIN (precr_ob_qh, MIPS_V8QI_FTYPE_V4HI_V4HI, dspr2),
+  DIRECT_BUILTIN (precr_sra_qh_pw, MIPS_V4HI_FTYPE_V2SI_V2SI_V2SI, dspr2_64),
+  DIRECT_BUILTIN (precr_sra_r_qh_pw, MIPS_V4HI_FTYPE_V2SI_V2SI_V2SI, dspr2_64),
+  DIRECT_BUILTIN (prependd, MIPS_DI_FTYPE_DI_DI_DI, dspr2_64),
+  DIRECT_BUILTIN (prependw, MIPS_DI_FTYPE_DI_DI_DI, dspr2_64),
+  DIRECT_BUILTIN (shra_ob, MIPS_V8QI_FTYPE_V8QI_DI, dspr2_64),
+  DIRECT_BUILTIN (shra_r_ob, MIPS_V8QI_FTYPE_V8QI_DI, dspr2_64),
+  DIRECT_BUILTIN (shrl_qh, MIPS_V4HI_FTYPE_V4HI_DI, dspr2_64),
+  DIRECT_BUILTIN (subu_qh, MIPS_V4HI_FTYPE_V4HI_V4HI, dspr2_64),
+  DIRECT_BUILTIN (subu_s_qh, MIPS_V4HI_FTYPE_V4HI_V4HI, dspr2_64),
+  DIRECT_BUILTIN (subuh_ob, MIPS_V8QI_FTYPE_V8QI_V8QI, dspr2_64),
+  DIRECT_BUILTIN (subuh_r_ob, MIPS_V8QI_FTYPE_V8QI_V8QI, dspr2_64),
+
   /* Builtin functions for ST Microelectronics Loongson-2E/2F cores.  */
   LOONGSON_BUILTIN (packsswh, MIPS_V4HI_FTYPE_V2SI_V2SI),
   LOONGSON_BUILTIN (packsshb, MIPS_V8QI_FTYPE_V4HI_V4HI),
@@ -13298,6 +13325,7 @@  mips_build_cvpointer_type (void)
 #define MIPS_ATYPE_SI intSI_type_node
 #define MIPS_ATYPE_USI unsigned_intSI_type_node
 #define MIPS_ATYPE_DI intDI_type_node
+#define MIPS_ATYPE_TI intTI_type_node
 #define MIPS_ATYPE_UDI unsigned_intDI_type_node
 #define MIPS_ATYPE_SF float_type_node
 #define MIPS_ATYPE_DF double_type_node
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index e821041..e174eb7 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -10789,6 +10789,30 @@  a64 __builtin_mips_dpaqx_s_w_ph (a64, v2q15, v2q15);
 a64 __builtin_mips_dpaqx_sa_w_ph (a64, v2q15, v2q15);
 a64 __builtin_mips_dpsqx_s_w_ph (a64, v2q15, v2q15);
 a64 __builtin_mips_dpsqx_sa_w_ph (a64, v2q15, v2q15);
+v8qi __builtin_mips_absq_s_ob (v8qi);
+v4hi __builtin_mips_addu_qh (v4hi, v4hi);
+v4hi __builtin_mips_addu_s_qh (v4hi, v4hi);
+v8qi __builtin_mips_adduh_ob (v8qi, v8qi);
+v8qi __builtin_mips_adduh_r_ob (v8qi, v8qi);
+a64 __builtin_mips_dappend(a64, a64, a64);
+a64 __builtin_mips_dbalign (a64, a64, a64);
+a64 __builtin_mips_cmpgdu_eq_ob (v8qi, v8qi);
+a64 __builtin_mips_cmpgdu_lt_ob (v8qi, v8qi);
+a64 __builtin_mips_cmpgdu_le_ob (v8qi, v8qi);
+__m128i __builtin_mips_dpa_w_qh (__m128i, v4hi, v4hi);
+__m128i __builtin_mips_dps_w_qh (__m128i, v4hi, v4hi);
+v8qi __builtin_mips_precr_ob_qh (v4hi, v4hi);
+v4hi __builtin_mips_precr_sra_qh_pw (v2si, v2si, v2si);
+v4hi __builtin_mips_precr_sra_r_qh_pw (v2si, v2si, v2si);
+a64 __builtin_mips_prependd (a64, a64, a64);
+a64 __builtin_mips_prependw (a64, a64, a64);
+v8qi __builtin_mips_shra_ob (v8qi, a64);
+v8qi __builtin_mips_shra_r_ob (v8qi, a64);
+v4hi __builtin_mips_shrl_qh (v4hi, a64);
+v4hi __builtin_mips_subu_qh (v4hi, v4hi);
+v4hi __builtin_mips_subu_s_qh (v4hi, v4hi);
+v8qi __builtin_mips_subuh_ob (v8qi, v8qi);
+v8qi __builtin_mips_subuh_r_ob (v8qi, v8qi);
 @end smallexample
 
 
diff --git a/gcc/testsuite/gcc.target/mips/mips64-dspr2.c b/gcc/testsuite/gcc.target/mips/mips64-dspr2.c
new file mode 100644
index 0000000..046192e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/mips64-dspr2.c
@@ -0,0 +1,197 @@ 
+/* Test MIPS64 DSP REV 2 instructions */
+/* { dg-do run } */
+/* { dg-options "-mgp64 -mdspr2" } */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <assert.h>
+#include <limits.h>
+
+typedef signed char v8qi __attribute__ ((vector_size(8)));
+typedef short v4hi __attribute__ ((vector_size(8)));
+typedef int v2si __attribute__ ((vector_size(8)));
+typedef long long a64;
+
+void abort (void);
+
+//NOMIPS16 void test_MIPS64_DSPR2 (void);
+void test_MIPS64_DSPR2 (void);
+
+int little_endian;
+
+int main ()
+{
+  union { long long ll; int i[2]; } endianness_test;
+  endianness_test.ll = 1;
+  little_endian = endianness_test.i[0];
+
+  test_MIPS64_DSPR2 ();
+
+  return 0;
+}
+
+void test_MIPS64_DSPR2 ()
+{
+  v4hi v4hi_a,v4hi_b,v4hi_c,v4hi_r,v4hi_s;
+  v2si v2si_a,v2si_b,v2si_c,v2si_r,v2si_s;
+  v8qi v8qi_a,v8qi_b,v8qi_c,v8qi_r,v8qi_s;
+  a64 a64_a, a64_b, a64_c, a64_r, a64_s;
+
+  long long r, s;
+
+  v8qi_a = (v8qi) {0x11, 0x32, 0x00, 0x13, 0x14, 0x43, 0x32, 0x31};
+  v8qi_s = (v8qi) {0x11, 0x32, 0x00, 0x13, 0x17, 0x43, 0x32, 0x31};
+  v8qi_r = __builtin_mips_absq_s_ob (v8qi_a);
+  r = (long long) v8qi_r;
+  s = (long long) v8qi_s;
+  if (r != s)
+    abort ();
+
+  v4hi_a = (v4hi) {0x1fff, 0x1168, 0x8900, 0x5412};
+  v4hi_b = (v4hi) {0x3434, 0x1561, 0x2812, 0x0100};
+  v4hi_s = (v4hi) {0x5433, 0x26c9, 0xb112, 0x5512};
+  v4hi_r = __builtin_mips_addu_qh (v4hi_a, v4hi_b);
+  r = (long long) v4hi_r;
+  s = (long long) v4hi_s;
+  if (r != s)
+    abort ();
+
+  v4hi_a = (v4hi) {0x1111, 0x1234, 0x6574, 0x3498};
+  v4hi_b = (v4hi) {0x2222, 0x3265, 0x1254, 0x1212};
+  v4hi_s = (v4hi) {0x3333, 0x4499, 0x77c8, 0x46aa};
+  v4hi_r = __builtin_mips_addu_s_qh (v4hi_a, v4hi_b);
+  r = (long long) v4hi_r;
+  s = (long long) v4hi_s;
+  if (r != s)
+    abort ();
+
+  v8qi_a = (v8qi) {0x11, 0x12, 0x32, 0x34, 0x56, 0x12, 0x14, 0x34};
+  v8qi_b = (v8qi) {0x33, 0x12, 0x53, 0x56, 0x12, 0x34, 0x45, 0x65};
+  v8qi_s = (v8qi) {0x22, 0x12, 0x42, 0x45, 0x34, 0x22, 0x2c, 0x4c};
+  v8qi_r = __builtin_mips_adduh_ob (v8qi_a, v8qi_b);
+  r = (long long) v8qi_r;
+  s = (long long) v8qi_s;
+  if (r != s)
+    abort ();
+
+  v8qi_a = (v8qi) {0x12, 0x32, 0x13, 0x45, 0x00, 0x23, 0x44, 0x13};
+  v8qi_b = (v8qi) {0x34, 0x78, 0x34, 0x56, 0x44, 0x22, 0x11, 0x45};
+  v8qi_s = (v8qi) {0x23, 0x55, 0x24, 0x3e, 0x22, 0x23, 0x2b, 0x2c};
+  v8qi_r = __builtin_mips_adduh_r_ob (v8qi_a, v8qi_b);
+  r = (long long) v8qi_r;
+  s = (long long) v8qi_s;
+  if (r != s)
+    abort ();
+
+  a64_a = (a64) 0x1234567812345678;
+  a64_b = (a64) 0x1234567898765432;
+  a64_c = (a64) 0x1234567823543543;
+  a64_s = (a64) 0x91a2b3c091a2b3c2;
+  a64_r = __builtin_mips_dappend (a64_a, a64_b, a64_c);
+  r = (long long) a64_r;
+  s = (long long) a64_s;
+  if (r != s)
+    abort ();
+
+  a64_a = (a64) 0x1234567812345678;
+  a64_b = (a64) 0x1234567834561234;
+  a64_c = (a64) 0x0000000000000003;
+  a64_s = (a64) 0x7812345678123456;
+  a64_r = __builtin_mips_abalign (a64_a, a64_b, a64_c);
+  r = (long long) a64_r;
+  s = (long long) a64_s;
+  if (r != s)
+    abort ();
+
+  v8qi_a = (v8qi) {0x11, 0x12, 0x13, 0x14, 0x16, 0x17, 0x18, 0x10};
+  v8qi_b = (v8qi) {0x11, 0x12, 0x13, 0x14, 0x16, 0x17, 0x18, 0x10};
+  a64_s = (a64) 0x00000000000000ff;
+  a64_r = __builtin_mips_cmpgdu_eq_ob (v8qi_a, v8qi_b);
+  r = (long long) a64_r;
+  s = (long long) a64_s;
+  if (r != s)
+    abort ();
+
+  v8qi_a = (v8qi) {0x11, 0x12, 0x13, 0x14, 0x16, 0x17, 0x18, 0x20};
+  v8qi_b = (v8qi) {0x10, 0x11, 0x11, 0x11, 0x14, 0x13, 0x12, 0x15};
+  a64_s = (a64) 0x00000000000000ff;
+  a64_r = __builtin_mips_cmpgdu_lt_ob (v8qi_a, v8qi_b);
+  r = (long long) a64_r;
+  s = (long long) a64_s;
+  if (r != s)
+    abort ();
+
+  v8qi_a = (v8qi) {0x11, 0x12, 0x13, 0x14, 0x16, 0x17, 0x18, 0x20};
+  v8qi_b = (v8qi) {0x10, 0x11, 0x13, 0x11, 0x16, 0x13, 0x18, 0x15};
+  a64_s = (a64) 0x00000000000000ff;
+  a64_r = __builtin_mips_cmpgdu_le_ob (v8qi_a, v8qi_b);
+  r = (long long) a64_r;
+  s = (long long) a64_s;
+  if (r != s)
+    abort ();
+
+  v4hi_a = (v4hi) {0x1111, 0x2000, 0x1234, 0x7890};
+  v4hi_b = (v4hi) {0x4321, 0x4567, 0x2345, 0x7654};
+  v8qi_s = (v8qi) {0x90, 0x34, 0x00, 0x11, 0x21, 0x67, 0x45, 0x54};
+  v8qi_r = __builtin_mips_precr_ob_qh (v4hi_a, v4hi_b);
+  r = (long long) v8qi_r;
+  s = (long long) v8qi_s;
+  if (r != s)
+    abort ();
+
+  v2si_a = (v2si) {0x12345678, 0x43215678};
+  v2si_b = (v2si) {0x45679876, 0x23456543};
+  v2si_c = (v2si) {0x12345678, 0x22222000};
+  v4hi_s = (v4hi) {0x5678, 0x5678, 0x9876, 0x6543};
+  v4hi_r = __builtin_mips_precr_sra_qh_pw (v2si_a, v2si_b, v2si_c);
+  r = (long long) v4hi_r;
+  s = (long long) v4hi_s;
+  if (r != s)
+    abort ();
+
+  v2si_a = (v2si) {0x12345678, 0x89076656};
+  v2si_b = (v2si) {0x23457658, 0x48727345};
+  v2si_c = (v2si) {0x12434366, 0x34345000};
+  v4hi_s = (v4hi) {0x5678, 0x6656, 0x7658, 0x7345};
+  v4hi_r = __builtin_mips_precr_sra_r_qh_pw (v2si_a, v2si_b, v2si_c);
+  r = (long long) v4hi_r;
+  s = (long long) v4hi_s;
+  if (r != s)
+    abort ();
+
+  v4hi_a = (v4hi) {0x5432, 0x8764, 0x2234, 0x5476};
+  v4hi_b = (v4hi) {0x3424, 0x5323, 0x1356, 0x4352};
+  v4hi_s = (v4hi) {0x2003, 0x3441, 0x0ede, 0x1124};
+  v4hi_r = __builtin_mips_subu_qh (v4hi_a, v4hi_b);
+  r = (long long) v4hi_r;
+  s = (long long) v4hi_s;
+  if (r != s)
+    abort ();
+
+  v4hi_a = (v4hi) {0x8432, 0x8964, 0x4234, 0x8476};
+  v4hi_b = (v4hi) {0x3924, 0x5723, 0x2356, 0x3052};
+  v4hi_s = (v4hi) {0x4b0e, 0x3241, 0x1ede, 0x5424};
+  v4hi_r = __builtin_mips_subu_s_qh (v4hi_a, v4hi_b);
+  r = (long long) v4hi_r;
+  s = (long long) v4hi_s;
+  if (r != s)
+    abort ();
+
+  v8qi_a = (v8qi) {0x89, 0xe3, 0x64, 0x87, 0xee, 0xab, 0x8d, 0xd8};
+  v8qi_b = (v8qi) {0x11, 0x43, 0x56, 0x32, 0xaa, 0x76, 0x43, 0xa3};
+  v8qi_s = (v8qi) {0x78, 0xa0, 0x0e, 0x55, 0x44, 0x35, 0x4a, 0x35};
+  v8qi_r = __builtin_mips_subuh_ob (v8qi_a, v8qi_b);
+  r = (long long) v8qi_r;
+  s = (long long) v8qi_s;
+  if (r != s)
+    abort ();
+
+  v8qi_a = (v8qi) {0xe9, 0xa3, 0x84, 0xd7, 0xce, 0xab, 0xad, 0xd3};
+  v8qi_b = (v8qi) {0x31, 0x53, 0x36, 0x82, 0x8a, 0x56, 0x83, 0x33};
+  v8qi_s = (v8qi) {0xb8, 0x50, 0x4e, 0x55, 0x44, 0x55, 0x2a, 0xa0};
+  v8qi_r = __builtin_mips_subuh_r_ob (v8qi_a, v8qi_b);
+  r = (long long) v8qi_r;
+  s = (long long) v8qi_s;
+  if (r != s)
+    abort ();
+}
-- 
1.7.5.4