Index: testsuite/gcc.target/mips/mips64-dsp-ldx1.c
===================================================================
--- testsuite/gcc.target/mips/mips64-dsp-ldx1.c	(revision 0)
+++ testsuite/gcc.target/mips/mips64-dsp-ldx1.c	(revision 0)
@@ -0,0 +1,10 @@
+/* Test MIPS64 DSP instructions */
+/* { dg-do compile } */
+/* { dg-options "-mgp64 -mdsp" }  */
+
+/* { dg-final { scan-assembler "\tldx\t" } } */
+
+NOMIPS16 signed long long test (signed long long *a, int index)
+{
+  return __builtin_mips_ldx (a, index);
+}
Index: testsuite/gcc.target/mips/octeon2-lx-1.c
===================================================================
--- testsuite/gcc.target/mips/octeon2-lx-1.c	(revision 0)
+++ testsuite/gcc.target/mips/octeon2-lx-1.c	(revision 0)
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=octeon2 -O -mgp64" } */
+
+#define TEST(N, R, T) \
+  T f##N (T j, R *b, long long i) { return j + b[i]; } \
+  T g##N (T j, unsigned R *b, long long i) { return j + b[i]; }
+
+TEST (1, char, int)
+TEST (2, char, long long)
+/* { dg-final { scan-assembler-times "\tlbx\t" 2 } } */
+/* { dg-final { scan-assembler-times "\tlbux\t" 2 } } */
+TEST (3, short, int)
+TEST (4, short, long long)
+/* { dg-final { scan-assembler-times "\tlhx\t" 2 } } */
+/* { dg-final { scan-assembler-times "\tlhux\t" 2 } } */
+TEST (5, int, long long)
+/* { dg-final { scan-assembler-times "\tlwx\t" 1 } } */
+/* { dg-final { scan-assembler-times "\tlwux\t" 1 } } */
Index: testsuite/gcc.target/mips/mips64-dsp-ldx.c
===================================================================
--- testsuite/gcc.target/mips/mips64-dsp-ldx.c	(revision 0)
+++ testsuite/gcc.target/mips/mips64-dsp-ldx.c	(revision 0)
@@ -0,0 +1,10 @@
+/* Test MIPS64 DSP instructions */
+/* { dg-do compile } */
+/* { dg-options "-mgp64 -mdsp -O" } */
+
+/* { dg-final { scan-assembler "\tldx\t" } } */
+
+NOMIPS16 signed long long test (signed long long *a, int index)
+{
+  return a[index];
+}
Index: testsuite/gcc.target/mips/octeon2-lx-2.c
===================================================================
--- testsuite/gcc.target/mips/octeon2-lx-2.c	(revision 0)
+++ testsuite/gcc.target/mips/octeon2-lx-2.c	(revision 0)
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-march=octeon2 -O -mgp64" } */
+
+#define TEST(N, T) \
+  T f##N (T *p, int i) { return p[i]; } \
+  unsigned T g##N (unsigned T *p, int i) { return p[i]; }
+
+TEST (1, char)
+/* { dg-final { scan-assembler-times "\tlbu?x\t" 2 } } */
+TEST (2, short)
+/* { dg-final { scan-assembler-times "\tlhu?x\t" 2 } } */
+TEST (3, int)
+/* { dg-final { scan-assembler-times "\tlwx\t" 2 } } */
+TEST (4, long long)
+/* { dg-final { scan-assembler-times "\tldx\t" 2 } } */
Index: testsuite/gcc.target/mips/octeon2-lx-3.c
===================================================================
--- testsuite/gcc.target/mips/octeon2-lx-3.c	(revision 0)
+++ testsuite/gcc.target/mips/octeon2-lx-3.c	(revision 0)
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=octeon2 -O -mgp32" } */
+
+#define TEST(N, T) \
+  T f##N (T *p, int i) { return p[i]; } \
+  unsigned T g##N (unsigned T *p, int i) { return p[i]; }
+
+TEST (1, char)
+/* { dg-final { scan-assembler-times "\tlbu?x\t" 2 } } */
+TEST (2, short)
+/* { dg-final { scan-assembler-times "\tlhu?x\t" 2 } } */
+TEST (3, int)
+/* { dg-final { scan-assembler-times "\tlwx\t" 2 } } */
Index: config/mips/mips-dsp.md
===================================================================
--- config/mips/mips-dsp.md	(revision 182342)
+++ config/mips/mips-dsp.md	(working copy)
@@ -1105,20 +1105,21 @@ (define_expand "mips_lbux"
   "ISA_HAS_DSP"
 {
   operands[2] = convert_to_mode (Pmode, operands[2], false);
-  emit_insn (PMODE_INSN (gen_mips_lbux,
+  emit_insn (PMODE_INSN (gen_mips_lbux_extsi,
 			 (operands[0], operands[1], operands[2])));
   DONE;
 })
 
-(define_insn "mips_lbux_<mode>"
-  [(set (match_operand:SI 0 "register_operand" "=d")
-   	(zero_extend:SI
-	  (mem:QI (plus:P (match_operand:P 1 "register_operand" "d")
-			  (match_operand:P 2 "register_operand" "d")))))]
-  "ISA_HAS_DSP"
-  "lbux\t%0,%2(%1)"
+(define_insn "mips_l<SHORT:size><u>x_ext<GPR:mode>_<P:mode>"
+  [(set (match_operand:GPR 0 "register_operand" "=d")
+   	(any_extend:GPR
+	  (mem:SHORT (plus:P (match_operand:P 1 "register_operand" "d")
+			     (match_operand:P 2 "register_operand" "d")))))]
+  "ISA_HAS_L<SHORT:SIZE><U>X"
+  "l<SHORT:size><u>x\t%0,%2(%1)"
   [(set_attr "type"	"load")
-   (set_attr "mode"	"SI")])
+   (set_attr "mode"	"<GPR:MODE>")
+   (set_attr "length"	"4")])
 
 (define_expand "mips_lhx"
   [(match_operand:SI 0 "register_operand")
@@ -1127,21 +1128,11 @@ (define_expand "mips_lhx"
   "ISA_HAS_DSP"
 {
   operands[2] = convert_to_mode (Pmode, operands[2], false);
-  emit_insn (PMODE_INSN (gen_mips_lhx,
+  emit_insn (PMODE_INSN (gen_mips_lhx_extsi,
 			 (operands[0], operands[1], operands[2])));
   DONE;
 })
 
-(define_insn "mips_lhx_<mode>"
-  [(set (match_operand:SI 0 "register_operand" "=d")
-	(sign_extend:SI
-	  (mem:HI (plus:P (match_operand:P 1 "register_operand" "d")
-			  (match_operand:P 2 "register_operand" "d")))))]
-  "ISA_HAS_DSP"
-  "lhx\t%0,%2(%1)"
-  [(set_attr "type"	"load")
-   (set_attr "mode"	"SI")])
-
 (define_expand "mips_lwx"
   [(match_operand:SI 0 "register_operand")
    (match_operand 1 "pmode_register_operand")
@@ -1154,14 +1145,38 @@ (define_expand "mips_lwx"
   DONE;
 })
 
-(define_insn "mips_lwx_<mode>"
-  [(set (match_operand:SI 0 "register_operand" "=d")
-	(mem:SI (plus:P (match_operand:P 1 "register_operand" "d")
-	    		(match_operand:P 2 "register_operand" "d"))))]
-  "ISA_HAS_DSP"
-  "lwx\t%0,%2(%1)"
+(define_expand "mips_ldx"
+  [(match_operand:DI 0 "register_operand")
+   (match_operand 1 "pmode_register_operand")
+   (match_operand:SI 2 "register_operand")]
+  "ISA_HAS_DSP && TARGET_64BIT"
+{
+  operands[2] = convert_to_mode (Pmode, operands[2], false);
+  emit_insn (PMODE_INSN (gen_mips_ldx,
+			 (operands[0], operands[1], operands[2])));
+  DONE;
+})
+
+(define_insn "mips_l<GPR:size>x_<P:mode>"
+  [(set (match_operand:GPR 0 "register_operand" "=d")
+	(mem:GPR (plus:P (match_operand:P 1 "register_operand" "d")
+			 (match_operand:P 2 "register_operand" "d"))))]
+  "ISA_HAS_L<GPR:SIZE>X"
+  "l<GPR:size>x\t%0,%2(%1)"
+  [(set_attr "type"	"load")
+   (set_attr "mode"	"<GPR:MODE>")
+   (set_attr "length"	"4")])
+
+(define_insn "*mips_lw<u>x_<P:mode>_ext"
+  [(set (match_operand:DI 0 "register_operand" "=d")
+   	(any_extend:DI
+	  (mem:SI (plus:P (match_operand:P 1 "register_operand" "d")
+			     (match_operand:P 2 "register_operand" "d")))))]
+  "ISA_HAS_LW<U>X && TARGET_64BIT"
+  "lw<u>x\t%0,%2(%1)"
   [(set_attr "type"	"load")
-   (set_attr "mode"	"SI")])
+   (set_attr "mode"	"DI")
+   (set_attr "length"	"4")])
 
 ;; Table 2-8. MIPS DSP ASE Instructions: Branch
 ;; BPOSGE32
Index: config/mips/mips-ftypes.def
===================================================================
--- config/mips/mips-ftypes.def	(revision 182342)
+++ config/mips/mips-ftypes.def	(working copy)
@@ -53,6 +53,7 @@ DEF_MIPS_FTYPE (4, (INT, V2SF, V2SF, V2S
 
 DEF_MIPS_FTYPE (2, (SI, DI, SI))
 DEF_MIPS_FTYPE (2, (SI, POINTER, SI))
+DEF_MIPS_FTYPE (2, (DI, POINTER, SI))
 DEF_MIPS_FTYPE (1, (SI, SI))
 DEF_MIPS_FTYPE (2, (SI, SI, SI))
 DEF_MIPS_FTYPE (3, (SI, SI, SI, SI))
Index: config/mips/mips.md
===================================================================
--- config/mips/mips.md	(revision 182342)
+++ config/mips/mips.md	(working copy)
@@ -668,9 +668,10 @@ (define_mode_attr D [(SI "") (DI "D")
 		     (HA "") (SA "") (DA "D")
 		     (UHA "") (USA "") (UDA "D")])
 
-;; This attribute gives the length suffix for a sign- or zero-extension
-;; instruction.
-(define_mode_attr size [(QI "b") (HI "h")])
+;; This attribute gives the length suffix for a sign-, zero-extension
+;; load and store instruction.
+(define_mode_attr size [(QI "b") (HI "h") (SI "w") (DI "d")])
+(define_mode_attr SIZE [(QI "B") (HI "H") (SI "W") (DI "D")])
 
 ;; This attributes gives the mode mask of a SHORT.
 (define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
@@ -790,6 +791,9 @@ (define_code_attr u [(sign_extend "") (z
 		     (lt "") (ltu "u")
 		     (le "") (leu "u")])
 
+;; <U> is like <u> except uppercase.
+(define_code_attr U [(sign_extend "") (zero_extend "U")])
+
 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
 
Index: config/mips/mips.c
===================================================================
--- config/mips/mips.c	(revision 182342)
+++ config/mips/mips.c	(working copy)
@@ -2159,6 +2159,29 @@ mips_lwxs_address_p (rtx addr)
     }
   return false;
 }
+
+/* Return true if ADDR matches the pattern for the L{B,H,W,D}{,U}X load 
+   indexed address instruction.  Note that such addresses are
+   not considered legitimate in the TARGET_LEGITIMATE_ADDRESS_P
+   sense, because their use is so restricted.  */
+
+static bool
+mips_loadindexed_address_p (rtx addr, enum machine_mode mode)
+{
+  if (GET_CODE (addr) != PLUS
+      || !REG_P (XEXP (addr, 0))
+      || !REG_P (XEXP (addr, 1)))
+    return false;
+  if (ISA_HAS_LBX && mode == QImode)
+    return true;
+  if (ISA_HAS_LHX && mode == HImode)
+    return true;
+  if (ISA_HAS_LWX && mode == SImode)
+    return true;
+  if (ISA_HAS_LDX && mode == DImode)
+    return true;
+  return false;
+}
 
 /* Return true if a value at OFFSET bytes from base register BASE can be
    accessed using an unextended MIPS16 instruction.  MODE is the mode of
@@ -3552,6 +3575,11 @@ mips_rtx_costs (rtx x, int code, int out
 	  *total = COSTS_N_INSNS (2);
 	  return true;
 	}
+      if (mips_loadindexed_address_p (addr, mode))
+	{
+	  *total = COSTS_N_INSNS (2);
+	  return true;
+	}
       /* Otherwise use the default handling.  */
       return false;
 
@@ -12627,6 +12655,7 @@ AVAIL_NON_MIPS16 (mips3d, TARGET_MIPS3D)
 AVAIL_NON_MIPS16 (dsp, TARGET_DSP)
 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 (loongson, TARGET_LOONGSON_VECTORS)
 AVAIL_NON_MIPS16 (cache, TARGET_CACHE_BUILTIN)
@@ -12959,6 +12988,9 @@ static const struct mips_builtin_descrip
   DIRECT_BUILTIN (mult, MIPS_DI_FTYPE_SI_SI, dsp_32),
   DIRECT_BUILTIN (multu, MIPS_DI_FTYPE_USI_USI, dsp_32),
 
+  /* Built-in functions for the DSP ASE (64-bit only).  */
+  DIRECT_BUILTIN (ldx, MIPS_DI_FTYPE_POINTER_SI, dsp_64),
+
   /* The following are for the MIPS DSP ASE REV 2 (32-bit only).  */
   DIRECT_BUILTIN (dpa_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32),
   DIRECT_BUILTIN (dps_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32),
Index: config/mips/mips.h
===================================================================
--- config/mips/mips.h	(revision 182342)
+++ config/mips/mips.h	(working copy)
@@ -996,6 +996,15 @@ struct mips_cpu_info {
 /* ISA has lwxs instruction (load w/scaled index address.  */
 #define ISA_HAS_LWXS		(TARGET_SMARTMIPS && !TARGET_MIPS16)
 
+/* ISA has lbx, lbux, lhx, lhx, lhux, lwx, lwux, or ldx instruction. */
+#define ISA_HAS_LBX		(TARGET_OCTEON2)
+#define ISA_HAS_LBUX		(ISA_HAS_DSP || TARGET_OCTEON2)
+#define ISA_HAS_LHX		(ISA_HAS_DSP || TARGET_OCTEON2)
+#define ISA_HAS_LHUX		(TARGET_OCTEON2)
+#define ISA_HAS_LWX		(ISA_HAS_DSP || TARGET_OCTEON2)
+#define ISA_HAS_LWUX		(TARGET_OCTEON2 && TARGET_64BIT)
+#define ISA_HAS_LDX		((ISA_HAS_DSP || TARGET_OCTEON2) && TARGET_64BIT)
+
 /* The DSP ASE is available.  */
 #define ISA_HAS_DSP		(TARGET_DSP && !TARGET_MIPS16)
 
