diff --git a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
index a598c3f1db5..6daa632b7a3 100644
--- a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
+++ b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
@@ -948,7 +948,6 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
     llvm_unreachable("Unexpected asm memory constraint");
   // All memory constraints can at least accept raw pointers.
   case InlineAsm::Constraint_i:
-  case InlineAsm::Constraint_R:
     OutOps.push_back(Op);
     OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
     return false;
@@ -961,6 +960,20 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
     OutOps.push_back(Op);
     OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
     return false;
+  case InlineAsm::Constraint_R:
+    // The 'R' constraint is supposed to be much more complicated than this.
+    // However, it's becoming less useful due to architectural changes and
+    // ought to be replaced by other constraints such as 'ZC'.
+    // For now, support 9-bit signed offsets which is supportable by all
+    // subtargets for all instructions.
+    if (selectAddrRegImm9(Op, Base, Offset)) {
+      OutOps.push_back(Base);
+      OutOps.push_back(Offset);
+      return false;
+    }
+    OutOps.push_back(Op);
+    OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
+    return false;
   case InlineAsm::Constraint_ZC:
     // ZC matches whatever the pref, ll, and sc instructions can handle for the
     // given subtarget.
diff --git a/test/CodeGen/Mips/inlineasm_constraint.ll b/test/CodeGen/Mips/inlineasm_constraint.ll
index 76b73dc276a..868433e0941 100644
--- a/test/CodeGen/Mips/inlineasm_constraint.ll
+++ b/test/CodeGen/Mips/inlineasm_constraint.ll
@@ -51,14 +51,5 @@ entry:
 ; CHECK: #NO_APP	
   tail call i32 asm sideeffect "addiu $0,$1,$2", "=r,r,P"(i32 7, i32 65535) nounwind
 
-; Now R Which takes the address of c
-  %c = alloca i32, align 4
-  store i32 -4469539, i32* %c, align 4
-  %8 = call i32 asm sideeffect "lw $0, 1 + $1\0A\09lw $0, 2 + $1\0A\09", "=r,*R"(i32* %c) #1
-; CHECK: #APP
-; CHECK: lw ${{[0-9]+}}, 1 + 0(${{[0-9]+}})
-; CHECK: lw ${{[0-9]+}}, 2 + 0(${{[0-9]+}})
-; CHECK: #NO_APP	
-
   ret i32 0
 }
diff --git a/test/CodeGen/Mips/inlineasm_constraint_R.ll b/test/CodeGen/Mips/inlineasm_constraint_R.ll
new file mode 100644
index 00000000000..c4105ae6b22
--- /dev/null
+++ b/test/CodeGen/Mips/inlineasm_constraint_R.ll
@@ -0,0 +1,60 @@
+; RUN: llc -march=mipsel < %s | FileCheck %s
+
+@data = global [8193 x i32] zeroinitializer
+
+define void @R(i32 *%p) nounwind {
+entry:
+  ; CHECK-LABEL: R:
+
+  call void asm sideeffect "lw $$1, $0", "*R,~{$1}"(i32* getelementptr inbounds ([8193 x i32], [8193 x i32]* @data, i32 0, i32 0))
+
+  ; CHECK: lw $[[BASEPTR:[0-9]+]], %got(data)(
+  ; CHECK: #APP
+  ; CHECK: lw $1, 0($[[BASEPTR]])
+  ; CHECK: #NO_APP
+
+  ret void
+}
+
+define void @R_offset_4(i32 *%p) nounwind {
+entry:
+  ; CHECK-LABEL: R_offset_4:
+
+  call void asm sideeffect "lw $$1, $0", "*R,~{$1}"(i32* getelementptr inbounds ([8193 x i32], [8193 x i32]* @data, i32 0, i32 1))
+
+  ; CHECK: lw $[[BASEPTR:[0-9]+]], %got(data)(
+  ; CHECK: #APP
+  ; CHECK: lw $1, 4($[[BASEPTR]])
+  ; CHECK: #NO_APP
+
+  ret void
+}
+
+define void @R_offset_254(i32 *%p) nounwind {
+entry:
+  ; CHECK-LABEL: R_offset_254:
+
+  call void asm sideeffect "lw $$1, $0", "*R,~{$1}"(i32* getelementptr inbounds ([8193 x i32], [8193 x i32]* @data, i32 0, i32 63))
+
+  ; CHECK-DAG: lw $[[BASEPTR:[0-9]+]], %got(data)(
+  ; CHECK: #APP
+  ; CHECK: lw $1, 252($[[BASEPTR]])
+  ; CHECK: #NO_APP
+
+  ret void
+}
+
+define void @R_offset_256(i32 *%p) nounwind {
+entry:
+  ; CHECK-LABEL: R_offset_256:
+
+  call void asm sideeffect "lw $$1, $0", "*R,~{$1}"(i32* getelementptr inbounds ([8193 x i32], [8193 x i32]* @data, i32 0, i32 64))
+
+  ; CHECK-DAG: lw $[[BASEPTR:[0-9]+]], %got(data)(
+  ; CHECK: addiu $[[BASEPTR2:[0-9]+]], $[[BASEPTR]], 256
+  ; CHECK: #APP
+  ; CHECK: lw $1, 0($[[BASEPTR2]])
+  ; CHECK: #NO_APP
+
+  ret void
+}