diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index f569dd98ac7092248aa91d3ad2aee9921d3d0859..ca622519b7de95a2585caa0db6e5591dba30b73e 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -49,7 +49,7 @@ enum arm_type_qualifiers
   qualifier_const = 0x2, /* 1 << 1  */
   /* T *foo.  */
   qualifier_pointer = 0x4, /* 1 << 2  */
-  /* const T * foo */
+  /* const T * foo.  */
   qualifier_const_pointer = 0x6,
   /* Used when expanding arguments if an operand could
      be an immediate.  */
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index a76c950c53dba315ea051cd451a64173025b89d9..418f1eabfc4f057f33dfc941e99b8292a7f3fd5e 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -31506,7 +31506,8 @@ arm_elf_section_type_flags (tree decl, const char *name, int reloc)
     false otherwise.  If a BUILTIN is passed for which this function has not
     been implemented it will cause an exception.  */
 
-bool arm_coproc_builtin_available (enum unspecv builtin)
+bool
+arm_coproc_builtin_available (enum unspecv builtin)
 {
   /* None of these builtins are available in Thumb mode if the target only
      supports Thumb-1.  */
@@ -31538,14 +31539,17 @@ bool arm_coproc_builtin_available (enum unspecv builtin)
 	  return true;
 	break;
       case VUNSPEC_MCRR:
-      case VUNSPEC_MCRR2:
       case VUNSPEC_MRRC:
-      case VUNSPEC_MRRC2:
 	/* Only present in ARMv5TE, ARMv6 (but not ARMv6-M), ARMv7* and
 	   ARMv8-{A,M}.  */
 	if (arm_arch6 || arm_arch5te)
 	  return true;
 	break;
+      case VUNSPEC_MCRR2:
+      case VUNSPEC_MRRC2:
+	if (arm_arch6)
+	  return true;
+	break;
       default:
 	gcc_unreachable ();
     }
@@ -31555,7 +31559,8 @@ bool arm_coproc_builtin_available (enum unspecv builtin)
 /* This function returns true if OP is a valid memory operand for the ldc and
    stc coprocessor instructions and false otherwise.  */
 
-bool arm_coproc_ldc_stc_legitimate_address (rtx op)
+bool
+arm_coproc_ldc_stc_legitimate_address (rtx op)
 {
   int range;
   /* Has to be a memory operand.  */
@@ -31585,7 +31590,7 @@ bool arm_coproc_ldc_stc_legitimate_address (rtx op)
 	  range = INTVAL (op);
 
 	  /* Within the range of [-1020,1020].  */
-	  if (range < -1020 || range > 1020)
+	  if (!IN_RANGE (range, -1020, 1020))
 	    return false;
 
 	  /* And a multiple of 4.  */
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 28f063c7a6bad7554b969518540b2869334ac7f8..3ff77f2bf09734f8a113ce969efa959f185ec443 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -11496,12 +11496,12 @@
 })
 
 (define_insn "<cdp>"
-  [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
-		     (match_operand:SI 1 "immediate_operand")
-		     (match_operand:SI 2 "immediate_operand")
-		     (match_operand:SI 3 "immediate_operand")
-		     (match_operand:SI 4 "immediate_operand")
-		     (match_operand:SI 5 "immediate_operand")] CDPI)]
+  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
+		     (match_operand:SI 1 "immediate_operand" "n")
+		     (match_operand:SI 2 "immediate_operand" "n")
+		     (match_operand:SI 3 "immediate_operand" "n")
+		     (match_operand:SI 4 "immediate_operand" "n")
+		     (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
   "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
 {
   arm_const_bounds (operands[0], 0, 16);
@@ -11515,32 +11515,51 @@
   [(set_attr "length" "4")
    (set_attr "type" "coproc")])
 
-(define_insn "*ldcstc"
+(define_insn "*stc"
+  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
+		     (match_operand:SI 1 "immediate_operand" "n")
+		     (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
+  "arm_coproc_builtin_available (VUNSPEC_<STC>)"
+{
+  arm_const_bounds (operands[0], 0, 16);
+  arm_const_bounds (operands[1], 0, (1 << 5));
+  return "<stc>\\tp%c0, CR%c1, %2";
+}
+  [(set_attr "length" "4")
+   (set_attr "type" "coproc")])
+
+(define_expand "<stc>"
   [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
 		     (match_operand:SI 1 "immediate_operand")
-		     (match_operand:SI 2 "memory_operand" "Uz")] LDCSTCI)]
-  "arm_coproc_builtin_available (VUNSPEC_<LDCSTC>)"
+		     (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
+  "arm_coproc_builtin_available (VUNSPEC_<STC>)")
+
+(define_insn "*ldc"
+  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
+		     (match_operand:SI 1 "immediate_operand" "n")
+		     (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
+  "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
 {
   arm_const_bounds (operands[0], 0, 16);
   arm_const_bounds (operands[1], 0, (1 << 5));
-  return "<ldcstc>\\tp%c0, CR%c1, %2";
+  return "<ldc>\\tp%c0, CR%c1, %2";
 }
   [(set_attr "length" "4")
    (set_attr "type" "coproc")])
 
-(define_expand "<ldcstc>"
+(define_expand "<ldc>"
   [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
 		     (match_operand:SI 1 "immediate_operand")
-		     (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCSTCI)]
-  "arm_coproc_builtin_available (VUNSPEC_<LDCSTC>)")
+		     (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
+  "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
 
 (define_insn "<mcr>"
-  [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
-		     (match_operand:SI 1 "immediate_operand")
-		     (match_operand:SI 2 "s_register_operand")
-		     (match_operand:SI 3 "immediate_operand")
-		     (match_operand:SI 4 "immediate_operand")
-		     (match_operand:SI 5 "immediate_operand")] MCRI)
+  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
+		     (match_operand:SI 1 "immediate_operand" "n")
+		     (match_operand:SI 2 "s_register_operand" "r")
+		     (match_operand:SI 3 "immediate_operand" "n")
+		     (match_operand:SI 4 "immediate_operand" "n")
+		     (match_operand:SI 5 "immediate_operand" "n")] MCRI)
    (use (match_dup 2))]
   "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
 {
@@ -11555,12 +11574,12 @@
    (set_attr "type" "coproc")])
 
 (define_insn "<mrc>"
-  [(set (match_operand:SI 0 "s_register_operand")
-	(unspec_volatile [(match_operand:SI 1 "immediate_operand")
-			  (match_operand:SI 2 "immediate_operand")
-			  (match_operand:SI 3 "immediate_operand")
-			  (match_operand:SI 4 "immediate_operand")
-			  (match_operand:SI 5 "immediate_operand")] MRCI))]
+  [(set (match_operand:SI 0 "s_register_operand" "=r")
+	(unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
+			  (match_operand:SI 2 "immediate_operand" "n")
+			  (match_operand:SI 3 "immediate_operand" "n")
+			  (match_operand:SI 4 "immediate_operand" "n")
+			  (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
   "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
 {
   arm_const_bounds (operands[1], 0, 16);
@@ -11574,10 +11593,10 @@
    (set_attr "type" "coproc")])
 
 (define_insn "<mcrr>"
-  [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
-		     (match_operand:SI 1 "immediate_operand")
-		     (match_operand:DI 2 "s_register_operand")
-		     (match_operand:SI 3 "immediate_operand")] MCRRI)
+  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
+		     (match_operand:SI 1 "immediate_operand" "n")
+		     (match_operand:DI 2 "s_register_operand" "r")
+		     (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
    (use (match_dup 2))]
   "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
 {
@@ -11590,10 +11609,10 @@
    (set_attr "type" "coproc")])
 
 (define_insn "<mrrc>"
-  [(set (match_operand:DI 0 "s_register_operand")
-	(unspec_volatile [(match_operand:SI 1 "immediate_operand")
-			  (match_operand:SI 2 "immediate_operand")
-			  (match_operand:SI 3 "immediate_operand")] MRRCI))]
+  [(set (match_operand:DI 0 "s_register_operand" "=r")
+	(unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
+			  (match_operand:SI 2 "immediate_operand" "n")
+			  (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
   "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
 {
   arm_const_bounds (operands[1], 0, 16);
diff --git a/gcc/config/arm/arm_acle.h b/gcc/config/arm/arm_acle.h
index 68a5ede0e2eee5e416faf78baefb98776d03e82b..1de1e277d182003030f057c0349a8d059e24d8ae 100644
--- a/gcc/config/arm/arm_acle.h
+++ b/gcc/config/arm/arm_acle.h
@@ -146,13 +146,6 @@ __arm_mcrr (const unsigned int __coproc, const unsigned int __opc1,
   return __builtin_arm_mcrr (__coproc, __opc1, __value, __CRm);
 }
 
-__extension__ static __inline void __attribute__ ((__always_inline__))
-__arm_mcrr2 (const unsigned int __coproc, const unsigned int __opc1,
-	    uint64_t __value, const unsigned int __CRm)
-{
-  return __builtin_arm_mcrr2 (__coproc, __opc1, __value, __CRm);
-}
-
 __extension__ static __inline uint64_t __attribute__ ((__always_inline__))
 __arm_mrrc (const unsigned int __coproc, const unsigned int __opc1,
 	    const unsigned int __CRm)
@@ -160,12 +153,22 @@ __arm_mrrc (const unsigned int __coproc, const unsigned int __opc1,
   return __builtin_arm_mrrc (__coproc, __opc1, __CRm);
 }
 
+#if __ARM_ARCH >= 6
+
+__extension__ static __inline void __attribute__ ((__always_inline__))
+__arm_mcrr2 (const unsigned int __coproc, const unsigned int __opc1,
+	    uint64_t __value, const unsigned int __CRm)
+{
+  return __builtin_arm_mcrr2 (__coproc, __opc1, __value, __CRm);
+}
+
 __extension__ static __inline uint64_t __attribute__ ((__always_inline__))
 __arm_mrrc2 (const unsigned int __coproc, const unsigned int __opc1,
 	     const unsigned int __CRm)
 {
   return __builtin_arm_mrrc2 (__coproc, __opc1,  __CRm);
 }
+#endif /* __ARM_ARCH >= 6.  */
 #endif /* __ARM_ARCH >= 6 ||  defined (__ARM_ARCH_5TE__).  */
 #endif /*  __ARM_ARCH >= 5.  */
 #endif /* (!__thumb__ || __thumb2__) &&  __ARM_ARCH >= 4.  */
diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md
index a1d0019f3bae95b0a130e007f718bd5b7806c0eb..b04c35c755cdd8ea5c505654fa868d270c45b2a5 100644
--- a/gcc/config/arm/constraints.md
+++ b/gcc/config/arm/constraints.md
@@ -449,7 +449,7 @@
 
 (define_memory_constraint "Uz"
  "@internal
-  A memory access that is accessible"
+  A memory access that is accessible as an LDC/STC operand"
  (and (match_code "mem")
       (match_test "arm_coproc_ldc_stc_legitimate_address (op)")))
 
diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md
index 23b4293ad5b410c33c18a3e2012d53b816f0b37a..572affc3fdc158606340a7b4926f437fb9fddf7d 100644
--- a/gcc/config/arm/iterators.md
+++ b/gcc/config/arm/iterators.md
@@ -853,20 +853,23 @@
 (define_int_attr cdp [(VUNSPEC_CDP "cdp") (VUNSPEC_CDP2 "cdp2")])
 (define_int_attr CDP [(VUNSPEC_CDP "CDP") (VUNSPEC_CDP2 "CDP2")])
 
-;; An iterator for the LDC and STC coprocessor instructions
-(define_int_iterator LDCSTCI [VUNSPEC_LDC VUNSPEC_LDC2
-			      VUNSPEC_LDCL VUNSPEC_LDC2L
-			      VUNSPEC_STC VUNSPEC_STC2
-			      VUNSPEC_STCL VUNSPEC_STC2L])
-
-(define_int_attr ldcstc [(VUNSPEC_LDC "ldc") (VUNSPEC_LDC2 "ldc2")
-			 (VUNSPEC_LDCL "ldcl") (VUNSPEC_LDC2L "ldc2l")
-			 (VUNSPEC_STC "stc") (VUNSPEC_STC2 "stc2")
-			 (VUNSPEC_STCL "stcl") (VUNSPEC_STC2L "stc2l")])
-(define_int_attr LDCSTC [(VUNSPEC_LDC "LDC") (VUNSPEC_LDC2 "LDC2")
-			 (VUNSPEC_LDCL "LDCL") (VUNSPEC_LDC2L "LDC2L")
-			 (VUNSPEC_STC "STC") (VUNSPEC_STC2 "STC2")
-			 (VUNSPEC_STCL "STCL") (VUNSPEC_STC2L "STC2L")])
+;; An iterator for the LDC coprocessor instructions
+(define_int_iterator LDCI [VUNSPEC_LDC VUNSPEC_LDC2
+			   VUNSPEC_LDCL VUNSPEC_LDC2L])
+
+(define_int_attr ldc [(VUNSPEC_LDC "ldc") (VUNSPEC_LDC2 "ldc2")
+		      (VUNSPEC_LDCL "ldcl") (VUNSPEC_LDC2L "ldc2l")])
+(define_int_attr LDC [(VUNSPEC_LDC "LDC") (VUNSPEC_LDC2 "LDC2")
+		      (VUNSPEC_LDCL "LDCL") (VUNSPEC_LDC2L "LDC2L")])
+
+;; An iterator for the STC coprocessor instructions
+(define_int_iterator STCI [VUNSPEC_STC VUNSPEC_STC2
+			   VUNSPEC_STCL VUNSPEC_STC2L])
+
+(define_int_attr stc [(VUNSPEC_STC "stc") (VUNSPEC_STC2 "stc2")
+		      (VUNSPEC_STCL "stcl") (VUNSPEC_STC2L "stc2l")])
+(define_int_attr STC [(VUNSPEC_STC "STC") (VUNSPEC_STC2 "STC2")
+		      (VUNSPEC_STCL "STCL") (VUNSPEC_STC2L "STC2L")])
 
 ;; An iterator for the MCR coprocessor instructions
 (define_int_iterator MCRI [VUNSPEC_MCR VUNSPEC_MCR2])
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index 0d4023e5056eac56c572197dc0fc12d454be0f85..fcedc64fcddb84e96a618b9bbf565ae588d8ba47 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -1620,14 +1620,14 @@ ARM target supports the following coprocessor instruction: @code{CDP},
 
 @item arm_coproc2_ok
 @anchor{arm_coproc2_ok}
-ARM target supports the all the coprocessor instructions also listed as
-supported in @ref{arm_coproc1_ok} and the following: @code{CDP2}, @code{LDC2},
+ARM target supports all the coprocessor instructions also listed as supported
+in @ref{arm_coproc1_ok} in addition to the following: @code{CDP2}, @code{LDC2},
 @code{LDC2l}, @code{STC2}, @code{STC2l}, @code{MCR2} and @code{MRC2}.
 
 @item arm_coproc3_ok
-ARM target supports the all the coprocessor instructions also listed as
-supported in @ref{arm_coproc2_ok} and the following: @code{MCRR}, @code{MCRR2},
-@code{MRRC}, and @code{MRRC2}.
+ARM target supports all the coprocessor instructions also listed as supported
+in @ref{arm_coproc2_ok} in addition to the following: @code{MCRR} and
+@code{MRRC}.
 @end table
 
 @subsubsection AArch64-specific attributes
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 9579744ba6435307458d2516d5e27767619424b0..2ff05568b0bb69273f4038823fd70f6b3ec7bde4 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -7103,14 +7103,14 @@ proc check_effective_target_arm_coproc2_ok { } {
 }
 
 # Return 1 if the target supports all coprocessor instructions checked by
-# check_effective_target_arm_coproc2_ok and the following: mcrr, mcrr2, mrrc
-# and mrrc2.
+# check_effective_target_arm_coproc2_ok in addition to the following: mcrr
+# and mrrc.
 proc check_effective_target_arm_coproc3_ok_nocache { } {
     if { ![check_effective_target_arm_coproc2_ok] } {
 	return 0
     }
     return [check_no_compiler_messages_nocache arm_coproc3_ok assembly {
-	#if __ARM_ARCH < 6 && !defined (__ARM_ARCH_5TE)
+	#if __ARM_ARCH < 6 && !defined (__ARM_ARCH_5TE__)
 	#error FOO
 	#endif
     }]
@@ -7120,3 +7120,22 @@ proc check_effective_target_arm_coproc3_ok { } {
     return [check_cached_effective_target arm_coproc3_ok \
 		check_effective_target_arm_coproc3_ok_nocache]
 }
+
+# Return 1 if the target supports all coprocessor instructions checked by
+# check_effective_target_arm_coproc3_ok in addition to the following: mcrr2
+# and mrrc2.
+proc check_effective_target_arm_coproc4_ok_nocache { } {
+    if { ![check_effective_target_arm_coproc3_ok] } {
+	return 0
+    }
+    return [check_no_compiler_messages_nocache arm_coproc4_ok assembly {
+	#if __ARM_ARCH < 6
+	#error FOO
+	#endif
+    }]
+}
+
+proc check_effective_target_arm_coproc4_ok { } {
+    return [check_cached_effective_target arm_coproc4_ok \
+		check_effective_target_arm_coproc4_ok_nocache]
+}
