diff mbox

[MIPS] Update the ZC constraint for MIPSR6 and use it

Message ID 6D39441BF12EF246A7ABCE6654B0235320F9651B@LEMAIL01.le.imgtec.org
State New
Headers show

Commit Message

Matthew Fortune Jan. 6, 2015, 12:42 p.m. UTC
Update the ZC constraint for MIPSR6 to allow it to be used as the memory
operand for implementations of atomic operations.  Also switch the internal
implementation of atomic operations to use ZC instead of ZR.

This fix accurately describes the memory constraints for the LL and SC
instructions.  An offset can therefore be used to access a data item
(ie. %lo (<var>)) rather than always having to load the address into a
register.  Tested for mips32r2, mips32r6 and micromips.

gcc/

	* config/mips/constraints.md (ZC): Add support for R6 LL/SC
	offsets.
	(ZD): Update to use ISA_HAS_PREF_LL_SC_9BIT.
	* config/mips/mips.h (ISA_HAS_PREFETCH_9BIT): Rename to...
	(ISA_HAS_PREF_LL_SC_9BIT): ... this. New macro.
	* config/mips/sync.md (sync_compare_and_swap<mode>): Use ZC
	instead of ZR for the memory operand of LL/SC.
	(compare_and_swap_12, sync_add<mode>): Likewise.
	(sync_<optab>_12, sync_old_<optab>_12): Likewise.
	(sync_new_<optab>_12, sync_nand_12): Likewise.
	(sync_old_nand_12, sync_new_nand_12): Likewise.
	(sync_sub<mode>, sync_old_add<mode>): Likewise.
	(sync_old_sub<mode>, sync_new_add<mode>): Likewise.
	(sync_new_sub<mode>, sync_<optab><mode>): Likewise.
	(sync_old_<optab><mode>, sync_new_<optab><mode>"): Likewise.
	(sync_nand<mode>, sync_old_nand<mode>): Likewise.
	(sync_new_nand<mode>, sync_lock_test_and_set<mode>): Likewise.
	(test_and_set_12, atomic_compare_and_swap<mode>): Likewise.
	(atomic_exchange<mode>_llsc, atomic_fetch_add<mode>_llsc): Likewise.
	* doc/md.texi (ZC): Update description.

OK to commit?

Thanks,
Matthew

---
 gcc/config/mips/constraints.md | 14 ++++++------
 gcc/config/mips/mips.h         |  4 ++--
 gcc/config/mips/sync.md        | 50 +++++++++++++++++++++---------------------
 gcc/doc/md.texi                |  8 +++----
 4 files changed, 37 insertions(+), 39 deletions(-)

Comments

Moore, Catherine Jan. 14, 2015, 7:30 p.m. UTC | #1
Hi Matthew,

> -----Original Message-----
> From: Matthew Fortune [mailto:Matthew.Fortune@imgtec.com]
> Sent: Tuesday, January 06, 2015 7:43 AM
> To: Moore, Catherine
> Cc: 'gcc-patches@gcc.gnu.org' (gcc-patches@gcc.gnu.org)
> Subject: [MIPS] Update the ZC constraint for MIPSR6 and use it
> 
> Update the ZC constraint for MIPSR6 to allow it to be used as the memory
> operand for implementations of atomic operations.  Also switch the internal
> implementation of atomic operations to use ZC instead of ZR.
> 
> This fix accurately describes the memory constraints for the LL and SC
> instructions.  An offset can therefore be used to access a data item
> (ie. %lo (<var>)) rather than always having to load the address into a
> register.  Tested for mips32r2, mips32r6 and micromips.
> 
> gcc/
> 
> 	* config/mips/constraints.md (ZC): Add support for R6 LL/SC
> 	offsets.
> 	(ZD): Update to use ISA_HAS_PREF_LL_SC_9BIT.
> 	* config/mips/mips.h (ISA_HAS_PREFETCH_9BIT): Rename to...
> 	(ISA_HAS_PREF_LL_SC_9BIT): ... this. New macro.
> 	* config/mips/sync.md (sync_compare_and_swap<mode>): Use ZC
> 	instead of ZR for the memory operand of LL/SC.
> 	(compare_and_swap_12, sync_add<mode>): Likewise.
> 	(sync_<optab>_12, sync_old_<optab>_12): Likewise.
> 	(sync_new_<optab>_12, sync_nand_12): Likewise.
> 	(sync_old_nand_12, sync_new_nand_12): Likewise.
> 	(sync_sub<mode>, sync_old_add<mode>): Likewise.
> 	(sync_old_sub<mode>, sync_new_add<mode>): Likewise.
> 	(sync_new_sub<mode>, sync_<optab><mode>): Likewise.
> 	(sync_old_<optab><mode>, sync_new_<optab><mode>"):
> Likewise.
> 	(sync_nand<mode>, sync_old_nand<mode>): Likewise.
> 	(sync_new_nand<mode>, sync_lock_test_and_set<mode>):
> Likewise.
> 	(test_and_set_12, atomic_compare_and_swap<mode>): Likewise.
> 	(atomic_exchange<mode>_llsc, atomic_fetch_add<mode>_llsc):
> Likewise.
> 	* doc/md.texi (ZC): Update description.
> 
> OK to commit?
> 
> diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
> index 9dad480..b608b17 100644
> --- a/gcc/config/mips/mips.h
> +++ b/gcc/config/mips/mips.h
> @@ -1089,8 +1089,8 @@ struct mips_cpu_info {
>  				  || mips_isa_rev >= 1)			\
>  				 && !TARGET_MIPS16)
> 
> -/* ISA has data prefetch with limited 9-bit displacement.  */
> -#define ISA_HAS_PREFETCH_9BIT	(mips_isa_rev >= 6)
> +/* ISA has data prefetch, LL and SC with limited 9-bit displacement.  */
> +#define ISA_HAS_PREF_LL_SC_9BIT	(mips_isa_rev >= 6)
> 
I'd like to see this described as something more general.  Say:
ISA_HAS_9BIT_DISPLACEMENT.   This patch is okay with that fixup.
Thanks,
Catherine
Matthew Fortune Jan. 14, 2015, 7:53 p.m. UTC | #2
Moore, Catherine <Catherine_Moore@mentor.com> writes
> Hi Matthew,
> 
> > -----Original Message-----
> > From: Matthew Fortune [mailto:Matthew.Fortune@imgtec.com]
> > Sent: Tuesday, January 06, 2015 7:43 AM
> > To: Moore, Catherine
> > Cc: 'gcc-patches@gcc.gnu.org' (gcc-patches@gcc.gnu.org)
> > Subject: [MIPS] Update the ZC constraint for MIPSR6 and use it
> >
> > Update the ZC constraint for MIPSR6 to allow it to be used as the
> > memory operand for implementations of atomic operations.  Also switch
> > the internal implementation of atomic operations to use ZC instead of
> ZR.
> >
> > This fix accurately describes the memory constraints for the LL and SC
> > instructions.  An offset can therefore be used to access a data item
> > (ie. %lo (<var>)) rather than always having to load the address into a
> > register.  Tested for mips32r2, mips32r6 and micromips.
> >
> > gcc/
> >
> > 	* config/mips/constraints.md (ZC): Add support for R6 LL/SC
> > 	offsets.
> > 	(ZD): Update to use ISA_HAS_PREF_LL_SC_9BIT.
> > 	* config/mips/mips.h (ISA_HAS_PREFETCH_9BIT): Rename to...
> > 	(ISA_HAS_PREF_LL_SC_9BIT): ... this. New macro.
> > 	* config/mips/sync.md (sync_compare_and_swap<mode>): Use ZC
> > 	instead of ZR for the memory operand of LL/SC.
> > 	(compare_and_swap_12, sync_add<mode>): Likewise.
> > 	(sync_<optab>_12, sync_old_<optab>_12): Likewise.
> > 	(sync_new_<optab>_12, sync_nand_12): Likewise.
> > 	(sync_old_nand_12, sync_new_nand_12): Likewise.
> > 	(sync_sub<mode>, sync_old_add<mode>): Likewise.
> > 	(sync_old_sub<mode>, sync_new_add<mode>): Likewise.
> > 	(sync_new_sub<mode>, sync_<optab><mode>): Likewise.
> > 	(sync_old_<optab><mode>, sync_new_<optab><mode>"):
> > Likewise.
> > 	(sync_nand<mode>, sync_old_nand<mode>): Likewise.
> > 	(sync_new_nand<mode>, sync_lock_test_and_set<mode>):
> > Likewise.
> > 	(test_and_set_12, atomic_compare_and_swap<mode>): Likewise.
> > 	(atomic_exchange<mode>_llsc, atomic_fetch_add<mode>_llsc):
> > Likewise.
> > 	* doc/md.texi (ZC): Update description.
> >
> > OK to commit?
> >
> > diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index
> > 9dad480..b608b17 100644
> > --- a/gcc/config/mips/mips.h
> > +++ b/gcc/config/mips/mips.h
> > @@ -1089,8 +1089,8 @@ struct mips_cpu_info {
> >  				  || mips_isa_rev >= 1)			\
> >  				 && !TARGET_MIPS16)
> >
> > -/* ISA has data prefetch with limited 9-bit displacement.  */
> > -#define ISA_HAS_PREFETCH_9BIT	(mips_isa_rev >= 6)
> > +/* ISA has data prefetch, LL and SC with limited 9-bit displacement.
> */
> > +#define ISA_HAS_PREF_LL_SC_9BIT	(mips_isa_rev >= 6)
> >
> I'd like to see this described as something more general.  Say:
> ISA_HAS_9BIT_DISPLACEMENT.   This patch is okay with that fixup.

I think I'm OK with changing that but it does leave us with a different
issue of knowing which subset of instructions should check for 9-bit
displacement. I.e. not all instructions only have a 9-bit displacement.
A GCC 6 thing would be to look over all the ISA_HAS macros and perhaps
do some general improvement in the framework we have there. I don't
know exactly what I'd do but something a bit more table based seems
sensible.

Matthew
Moore, Catherine Jan. 14, 2015, 8:05 p.m. UTC | #3
> -----Original Message-----
> From: Matthew Fortune [mailto:Matthew.Fortune@imgtec.com]
> Sent: Wednesday, January 14, 2015 2:54 PM
> To: Moore, Catherine
> Cc: 'gcc-patches@gcc.gnu.org' (gcc-patches@gcc.gnu.org)
> Subject: RE: [MIPS] Update the ZC constraint for MIPSR6 and use it
> 
> Moore, Catherine <Catherine_Moore@mentor.com> writes
> > Hi Matthew,
> >
> > > -----Original Message-----
> > > From: Matthew Fortune [mailto:Matthew.Fortune@imgtec.com]
> > > Sent: Tuesday, January 06, 2015 7:43 AM
> > > To: Moore, Catherine
> > > Cc: 'gcc-patches@gcc.gnu.org' (gcc-patches@gcc.gnu.org)
> > > Subject: [MIPS] Update the ZC constraint for MIPSR6 and use it
> > >
> > > Update the ZC constraint for MIPSR6 to allow it to be used as the
> > > memory operand for implementations of atomic operations.  Also
> > > switch the internal implementation of atomic operations to use ZC
> > > instead of
> > ZR.
> > >
> > > This fix accurately describes the memory constraints for the LL and
> > > SC instructions.  An offset can therefore be used to access a data
> > > item (ie. %lo (<var>)) rather than always having to load the address
> > > into a register.  Tested for mips32r2, mips32r6 and micromips.
> > >
> > > gcc/
> > >
> > > 	* config/mips/constraints.md (ZC): Add support for R6 LL/SC
> > > 	offsets.
> > > 	(ZD): Update to use ISA_HAS_PREF_LL_SC_9BIT.
> > > 	* config/mips/mips.h (ISA_HAS_PREFETCH_9BIT): Rename to...
> > > 	(ISA_HAS_PREF_LL_SC_9BIT): ... this. New macro.
> > > 	* config/mips/sync.md (sync_compare_and_swap<mode>): Use ZC
> > > 	instead of ZR for the memory operand of LL/SC.
> > > 	(compare_and_swap_12, sync_add<mode>): Likewise.
> > > 	(sync_<optab>_12, sync_old_<optab>_12): Likewise.
> > > 	(sync_new_<optab>_12, sync_nand_12): Likewise.
> > > 	(sync_old_nand_12, sync_new_nand_12): Likewise.
> > > 	(sync_sub<mode>, sync_old_add<mode>): Likewise.
> > > 	(sync_old_sub<mode>, sync_new_add<mode>): Likewise.
> > > 	(sync_new_sub<mode>, sync_<optab><mode>): Likewise.
> > > 	(sync_old_<optab><mode>, sync_new_<optab><mode>"):
> > > Likewise.
> > > 	(sync_nand<mode>, sync_old_nand<mode>): Likewise.
> > > 	(sync_new_nand<mode>, sync_lock_test_and_set<mode>):
> > > Likewise.
> > > 	(test_and_set_12, atomic_compare_and_swap<mode>): Likewise.
> > > 	(atomic_exchange<mode>_llsc, atomic_fetch_add<mode>_llsc):
> > > Likewise.
> > > 	* doc/md.texi (ZC): Update description.
> > >
> > > OK to commit?
> > >
> > > diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index
> > > 9dad480..b608b17 100644
> > > --- a/gcc/config/mips/mips.h
> > > +++ b/gcc/config/mips/mips.h
> > > @@ -1089,8 +1089,8 @@ struct mips_cpu_info {
> > >  				  || mips_isa_rev >= 1)			\
> > >  				 && !TARGET_MIPS16)
> > >
> > > -/* ISA has data prefetch with limited 9-bit displacement.  */
> > > -#define ISA_HAS_PREFETCH_9BIT	(mips_isa_rev >= 6)
> > > +/* ISA has data prefetch, LL and SC with limited 9-bit displacement.
> > */
> > > +#define ISA_HAS_PREF_LL_SC_9BIT	(mips_isa_rev >= 6)
> > >
> > I'd like to see this described as something more general.  Say:
> > ISA_HAS_9BIT_DISPLACEMENT.   This patch is okay with that fixup.
> 
> I think I'm OK with changing that but it does leave us with a different issue of
> knowing which subset of instructions should check for 9-bit displacement.
> I.e. not all instructions only have a 9-bit displacement.

I'm open to a different name.  Do you have any other suggestions?   Can we just say >= R6?

> A GCC 6 thing would be to look over all the ISA_HAS macros and perhaps do
> some general improvement in the framework we have there. I don't know
> exactly what I'd do but something a bit more table based seems sensible.
> 
Sounds like a good idea.
Matthew Fortune Jan. 14, 2015, 8:26 p.m. UTC | #4
Moore, Catherine <Catherine_Moore@mentor.com> writes:
> > -----Original Message-----
> > From: Matthew Fortune [mailto:Matthew.Fortune@imgtec.com]
> > Sent: Wednesday, January 14, 2015 2:54 PM
> > To: Moore, Catherine
> > Cc: 'gcc-patches@gcc.gnu.org' (gcc-patches@gcc.gnu.org)
> > Subject: RE: [MIPS] Update the ZC constraint for MIPSR6 and use it
> >
> > Moore, Catherine <Catherine_Moore@mentor.com> writes
> > > Hi Matthew,
> > >
> > > > -----Original Message-----
> > > > From: Matthew Fortune [mailto:Matthew.Fortune@imgtec.com]
> > > > Sent: Tuesday, January 06, 2015 7:43 AM
> > > > To: Moore, Catherine
> > > > Cc: 'gcc-patches@gcc.gnu.org' (gcc-patches@gcc.gnu.org)
> > > > Subject: [MIPS] Update the ZC constraint for MIPSR6 and use it
> > > >
> > > > Update the ZC constraint for MIPSR6 to allow it to be used as the
> > > > memory operand for implementations of atomic operations.  Also
> > > > switch the internal implementation of atomic operations to use ZC
> > > > instead of
> > > ZR.
> > > >
> > > > This fix accurately describes the memory constraints for the LL
> > > > and SC instructions.  An offset can therefore be used to access a
> > > > data item (ie. %lo (<var>)) rather than always having to load the
> > > > address into a register.  Tested for mips32r2, mips32r6 and
> micromips.
> > > >
> > > > gcc/
> > > >
> > > > 	* config/mips/constraints.md (ZC): Add support for R6 LL/SC
> > > > 	offsets.
> > > > 	(ZD): Update to use ISA_HAS_PREF_LL_SC_9BIT.
> > > > 	* config/mips/mips.h (ISA_HAS_PREFETCH_9BIT): Rename to...
> > > > 	(ISA_HAS_PREF_LL_SC_9BIT): ... this. New macro.
> > > > 	* config/mips/sync.md (sync_compare_and_swap<mode>): Use ZC
> > > > 	instead of ZR for the memory operand of LL/SC.
> > > > 	(compare_and_swap_12, sync_add<mode>): Likewise.
> > > > 	(sync_<optab>_12, sync_old_<optab>_12): Likewise.
> > > > 	(sync_new_<optab>_12, sync_nand_12): Likewise.
> > > > 	(sync_old_nand_12, sync_new_nand_12): Likewise.
> > > > 	(sync_sub<mode>, sync_old_add<mode>): Likewise.
> > > > 	(sync_old_sub<mode>, sync_new_add<mode>): Likewise.
> > > > 	(sync_new_sub<mode>, sync_<optab><mode>): Likewise.
> > > > 	(sync_old_<optab><mode>, sync_new_<optab><mode>"):
> > > > Likewise.
> > > > 	(sync_nand<mode>, sync_old_nand<mode>): Likewise.
> > > > 	(sync_new_nand<mode>, sync_lock_test_and_set<mode>):
> > > > Likewise.
> > > > 	(test_and_set_12, atomic_compare_and_swap<mode>): Likewise.
> > > > 	(atomic_exchange<mode>_llsc, atomic_fetch_add<mode>_llsc):
> > > > Likewise.
> > > > 	* doc/md.texi (ZC): Update description.
> > > >
> > > > OK to commit?
> > > >
> > > > diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index
> > > > 9dad480..b608b17 100644
> > > > --- a/gcc/config/mips/mips.h
> > > > +++ b/gcc/config/mips/mips.h
> > > > @@ -1089,8 +1089,8 @@ struct mips_cpu_info {
> > > >  				  || mips_isa_rev >= 1)			\
> > > >  				 && !TARGET_MIPS16)
> > > >
> > > > -/* ISA has data prefetch with limited 9-bit displacement.  */
> > > > -#define ISA_HAS_PREFETCH_9BIT	(mips_isa_rev >= 6)
> > > > +/* ISA has data prefetch, LL and SC with limited 9-bit
> displacement.
> > > */
> > > > +#define ISA_HAS_PREF_LL_SC_9BIT	(mips_isa_rev >= 6)
> > > >
> > > I'd like to see this described as something more general.  Say:
> > > ISA_HAS_9BIT_DISPLACEMENT.   This patch is okay with that fixup.
> >
> > I think I'm OK with changing that but it does leave us with a
> > different issue of knowing which subset of instructions should check
> for 9-bit displacement.
> > I.e. not all instructions only have a 9-bit displacement.
> 
> I'm open to a different name.  Do you have any other suggestions?   Can
> we just say >= R6?

That is pretty much what it boils down to but I do like keeping all the
isa level checks in one place and giving names to things. I'll go with
your suggestion and leave the rest to a later general improvement.

Thanks,
Matthew

> > A GCC 6 thing would be to look over all the ISA_HAS macros and perhaps
> > do some general improvement in the framework we have there. I don't
> > know exactly what I'd do but something a bit more table based seems
> sensible.
> >
> Sounds like a good idea.
diff mbox

Patch

diff --git a/gcc/config/mips/constraints.md b/gcc/config/mips/constraints.md
index 816880c..f5f257d 100644
--- a/gcc/config/mips/constraints.md
+++ b/gcc/config/mips/constraints.md
@@ -309,23 +309,23 @@  (define_constraint "Yx"
    (match_operand 0 "low_bitmask_operand"))
 
 (define_memory_constraint "ZC"
-  "When compiling microMIPS code, this constraint matches a memory operand
-   whose address is formed from a base register and a 12-bit offset.  These
-   operands can be used for microMIPS instructions such as @code{ll} and
-   @code{sc}.  When not compiling for microMIPS code, @code{ZC} is
-   equivalent to @code{R}."
+  "A memory operand whose address is formed by a base register and offset
+   that is suitable for use in instructions with the same addressing mode
+   as @code{ll} and @code{sc}."
   (and (match_code "mem")
        (if_then_else
 	 (match_test "TARGET_MICROMIPS")
 	 (match_test "umips_12bit_offset_address_p (XEXP (op, 0), mode)")
-	 (match_test "mips_address_insns (XEXP (op, 0), mode, false)"))))
+	 (if_then_else (match_test "ISA_HAS_PREF_LL_SC_9BIT")
+	   (match_test "mips_9bit_offset_address_p (XEXP (op, 0), mode)")
+	   (match_test "mips_address_insns (XEXP (op, 0), mode, false)")))))
 
 (define_address_constraint "ZD"
   "An address suitable for a @code{prefetch} instruction, or for any other
    instruction with the same addressing mode as @code{prefetch}."
    (if_then_else (match_test "TARGET_MICROMIPS")
 		 (match_test "umips_12bit_offset_address_p (op, mode)")
-	  (if_then_else (match_test "ISA_HAS_PREFETCH_9BIT")
+	  (if_then_else (match_test "ISA_HAS_PREF_LL_SC_9BIT")
 			(match_test "mips_9bit_offset_address_p (op, mode)")
 			(match_test "mips_address_insns (op, mode, false)"))))
 
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 9dad480..b608b17 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -1089,8 +1089,8 @@  struct mips_cpu_info {
 				  || mips_isa_rev >= 1)			\
 				 && !TARGET_MIPS16)
 
-/* ISA has data prefetch with limited 9-bit displacement.  */
-#define ISA_HAS_PREFETCH_9BIT	(mips_isa_rev >= 6)
+/* ISA has data prefetch, LL and SC with limited 9-bit displacement.  */
+#define ISA_HAS_PREF_LL_SC_9BIT	(mips_isa_rev >= 6)
 
 /* ISA has data indexed prefetch instructions.  This controls use of
    'prefx', along with TARGET_HARD_FLOAT and TARGET_DOUBLE_FLOAT.
diff --git a/gcc/config/mips/sync.md b/gcc/config/mips/sync.md
index cf6c05b..72d2fe4 100644
--- a/gcc/config/mips/sync.md
+++ b/gcc/config/mips/sync.md
@@ -59,7 +59,7 @@  (define_insn "*memory_barrier"
 ;; Can be removed in favor of atomic_compare_and_swap below.
 (define_insn "sync_compare_and_swap<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
-	(match_operand:GPR 1 "memory_operand" "+ZR,ZR"))
+	(match_operand:GPR 1 "memory_operand" "+ZC,ZC"))
    (set (match_dup 1)
 	(unspec_volatile:GPR [(match_operand:GPR 2 "reg_or_0_operand" "dJ,dJ")
 			      (match_operand:GPR 3 "arith_operand" "I,d")]
@@ -89,7 +89,7 @@  (define_expand "sync_compare_and_swap<mode>"
 ;; Helper insn for mips_expand_atomic_qihi.
 (define_insn "compare_and_swap_12"
   [(set (match_operand:SI 0 "register_operand" "=&d,&d")
-	(match_operand:SI 1 "memory_operand" "+ZR,ZR"))
+	(match_operand:SI 1 "memory_operand" "+ZC,ZC"))
    (set (match_dup 1)
 	(unspec_volatile:SI [(match_operand:SI 2 "register_operand" "d,d")
 			     (match_operand:SI 3 "register_operand" "d,d")
@@ -106,7 +106,7 @@  (define_insn "compare_and_swap_12"
    (set_attr "sync_insn1_op2" "5")])
 
 (define_insn "sync_add<mode>"
-  [(set (match_operand:GPR 0 "memory_operand" "+ZR,ZR")
+  [(set (match_operand:GPR 0 "memory_operand" "+ZC,ZC")
 	(unspec_volatile:GPR
           [(plus:GPR (match_dup 0)
 		     (match_operand:GPR 1 "arith_operand" "I,d"))]
@@ -134,7 +134,7 @@  (define_expand "sync_<optab><mode>"
 
 ;; Helper insn for sync_<optab><mode>
 (define_insn "sync_<optab>_12"
-  [(set (match_operand:SI 0 "memory_operand" "+ZR")
+  [(set (match_operand:SI 0 "memory_operand" "+ZC")
 	(unspec_volatile:SI
           [(match_operand:SI 1 "register_operand" "d")
 	   (match_operand:SI 2 "register_operand" "d")
@@ -174,7 +174,7 @@  (define_expand "sync_old_<optab><mode>"
 ;; Helper insn for sync_old_<optab><mode>
 (define_insn "sync_old_<optab>_12"
   [(set (match_operand:SI 0 "register_operand" "=&d")
-	(match_operand:SI 1 "memory_operand" "+ZR"))
+	(match_operand:SI 1 "memory_operand" "+ZC"))
    (set (match_dup 1)
 	(unspec_volatile:SI
           [(match_operand:SI 2 "register_operand" "d")
@@ -217,7 +217,7 @@  (define_expand "sync_new_<optab><mode>"
 (define_insn "sync_new_<optab>_12"
   [(set (match_operand:SI 0 "register_operand" "=&d")
 	(unspec_volatile:SI
-          [(match_operand:SI 1 "memory_operand" "+ZR")
+          [(match_operand:SI 1 "memory_operand" "+ZC")
 	   (match_operand:SI 2 "register_operand" "d")
 	   (match_operand:SI 3 "register_operand" "d")
 	   (atomic_hiqi_op:SI (match_dup 0)
@@ -257,7 +257,7 @@  (define_expand "sync_nand<mode>"
 
 ;; Helper insn for sync_nand<mode>
 (define_insn "sync_nand_12"
-  [(set (match_operand:SI 0 "memory_operand" "+ZR")
+  [(set (match_operand:SI 0 "memory_operand" "+ZC")
 	(unspec_volatile:SI
           [(match_operand:SI 1 "register_operand" "d")
 	   (match_operand:SI 2 "register_operand" "d")
@@ -296,7 +296,7 @@  (define_expand "sync_old_nand<mode>"
 ;; Helper insn for sync_old_nand<mode>
 (define_insn "sync_old_nand_12"
   [(set (match_operand:SI 0 "register_operand" "=&d")
-	(match_operand:SI 1 "memory_operand" "+ZR"))
+	(match_operand:SI 1 "memory_operand" "+ZC"))
    (set (match_dup 1)
 	(unspec_volatile:SI
           [(match_operand:SI 2 "register_operand" "d")
@@ -337,7 +337,7 @@  (define_expand "sync_new_nand<mode>"
 (define_insn "sync_new_nand_12"
   [(set (match_operand:SI 0 "register_operand" "=&d")
 	(unspec_volatile:SI
-          [(match_operand:SI 1 "memory_operand" "+ZR")
+          [(match_operand:SI 1 "memory_operand" "+ZC")
 	   (match_operand:SI 2 "register_operand" "d")
 	   (match_operand:SI 3 "register_operand" "d")
 	   (match_operand:SI 4 "reg_or_0_operand" "dJ")]
@@ -360,7 +360,7 @@  (define_insn "sync_new_nand_12"
    (set_attr "sync_insn1_op2" "4")])
 
 (define_insn "sync_sub<mode>"
-  [(set (match_operand:GPR 0 "memory_operand" "+ZR")
+  [(set (match_operand:GPR 0 "memory_operand" "+ZC")
 	(unspec_volatile:GPR
           [(minus:GPR (match_dup 0)
 		      (match_operand:GPR 1 "register_operand" "d"))]
@@ -374,7 +374,7 @@  (define_insn "sync_sub<mode>"
 ;; Can be removed in favor of atomic_fetch_add below.
 (define_insn "sync_old_add<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
-	(match_operand:GPR 1 "memory_operand" "+ZR,ZR"))
+	(match_operand:GPR 1 "memory_operand" "+ZC,ZC"))
    (set (match_dup 1)
 	(unspec_volatile:GPR
           [(plus:GPR (match_dup 1)
@@ -389,7 +389,7 @@  (define_insn "sync_old_add<mode>"
 
 (define_insn "sync_old_sub<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=&d")
-	(match_operand:GPR 1 "memory_operand" "+ZR"))
+	(match_operand:GPR 1 "memory_operand" "+ZC"))
    (set (match_dup 1)
 	(unspec_volatile:GPR
           [(minus:GPR (match_dup 1)
@@ -404,7 +404,7 @@  (define_insn "sync_old_sub<mode>"
 
 (define_insn "sync_new_add<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
-        (plus:GPR (match_operand:GPR 1 "memory_operand" "+ZR,ZR")
+        (plus:GPR (match_operand:GPR 1 "memory_operand" "+ZC,ZC")
 		  (match_operand:GPR 2 "arith_operand" "I,d")))
    (set (match_dup 1)
 	(unspec_volatile:GPR
@@ -420,7 +420,7 @@  (define_insn "sync_new_add<mode>"
 
 (define_insn "sync_new_sub<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=&d")
-        (minus:GPR (match_operand:GPR 1 "memory_operand" "+ZR")
+        (minus:GPR (match_operand:GPR 1 "memory_operand" "+ZC")
 		   (match_operand:GPR 2 "register_operand" "d")))
    (set (match_dup 1)
 	(unspec_volatile:GPR
@@ -435,7 +435,7 @@  (define_insn "sync_new_sub<mode>"
    (set_attr "sync_insn1_op2" "2")])
 
 (define_insn "sync_<optab><mode>"
-  [(set (match_operand:GPR 0 "memory_operand" "+ZR,ZR")
+  [(set (match_operand:GPR 0 "memory_operand" "+ZC,ZC")
 	(unspec_volatile:GPR
           [(fetchop_bit:GPR (match_operand:GPR 1 "uns_arith_operand" "K,d")
 			      (match_dup 0))]
@@ -448,7 +448,7 @@  (define_insn "sync_<optab><mode>"
 
 (define_insn "sync_old_<optab><mode>"
   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
-	(match_operand:GPR 1 "memory_operand" "+ZR,ZR"))
+	(match_operand:GPR 1 "memory_operand" "+ZC,ZC"))
    (set (match_dup 1)
 	(unspec_volatile:GPR
           [(fetchop_bit:GPR (match_operand:GPR 2 "uns_arith_operand" "K,d")
@@ -463,7 +463,7 @@  (define_insn "sync_old_<optab><mode>"
 
 (define_insn "sync_new_<optab><mode>"
   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
-	(match_operand:GPR 1 "memory_operand" "+ZR,ZR"))
+	(match_operand:GPR 1 "memory_operand" "+ZC,ZC"))
    (set (match_dup 1)
 	(unspec_volatile:GPR
           [(fetchop_bit:GPR (match_operand:GPR 2 "uns_arith_operand" "K,d")
@@ -478,7 +478,7 @@  (define_insn "sync_new_<optab><mode>"
    (set_attr "sync_insn1_op2" "2")])
 
 (define_insn "sync_nand<mode>"
-  [(set (match_operand:GPR 0 "memory_operand" "+ZR,ZR")
+  [(set (match_operand:GPR 0 "memory_operand" "+ZC,ZC")
 	(unspec_volatile:GPR [(match_operand:GPR 1 "uns_arith_operand" "K,d")]
 	 UNSPEC_SYNC_OLD_OP))]
   "GENERATE_LL_SC"
@@ -490,7 +490,7 @@  (define_insn "sync_nand<mode>"
 
 (define_insn "sync_old_nand<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
-	(match_operand:GPR 1 "memory_operand" "+ZR,ZR"))
+	(match_operand:GPR 1 "memory_operand" "+ZC,ZC"))
    (set (match_dup 1)
         (unspec_volatile:GPR [(match_operand:GPR 2 "uns_arith_operand" "K,d")]
 	 UNSPEC_SYNC_OLD_OP))]
@@ -504,7 +504,7 @@  (define_insn "sync_old_nand<mode>"
 
 (define_insn "sync_new_nand<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
-	(match_operand:GPR 1 "memory_operand" "+ZR,ZR"))
+	(match_operand:GPR 1 "memory_operand" "+ZC,ZC"))
    (set (match_dup 1)
 	(unspec_volatile:GPR [(match_operand:GPR 2 "uns_arith_operand" "K,d")]
 	 UNSPEC_SYNC_NEW_OP))]
@@ -519,7 +519,7 @@  (define_insn "sync_new_nand<mode>"
 
 (define_insn "sync_lock_test_and_set<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
-	(match_operand:GPR 1 "memory_operand" "+ZR,ZR"))
+	(match_operand:GPR 1 "memory_operand" "+ZC,ZC"))
    (set (match_dup 1)
 	(unspec_volatile:GPR [(match_operand:GPR 2 "arith_operand" "I,d")]
 	 UNSPEC_SYNC_EXCHANGE))]
@@ -546,7 +546,7 @@  (define_expand "sync_lock_test_and_set<mode>"
 
 (define_insn "test_and_set_12"
   [(set (match_operand:SI 0 "register_operand" "=&d")
-	(match_operand:SI 1 "memory_operand" "+ZR"))
+	(match_operand:SI 1 "memory_operand" "+ZC"))
    (set (match_dup 1)
 	(unspec_volatile:SI [(match_operand:SI 2 "register_operand" "d")
 			     (match_operand:SI 3 "register_operand" "d")
@@ -576,7 +576,7 @@  (define_insn "atomic_compare_and_swap<mode>"
 	;; TODO: the obscuring unspec can be relaxed for permissive memory
 	;; models.
 	;; Same applies to other atomic_* patterns.
-	(unspec_volatile:GPR [(match_operand:GPR 2 "memory_operand" "+ZR,ZR")
+	(unspec_volatile:GPR [(match_operand:GPR 2 "memory_operand" "+ZC,ZC")
 			      (match_operand:GPR 3 "reg_or_0_operand" "dJ,dJ")]
 	 UNSPEC_ATOMIC_COMPARE_AND_SWAP))
    (set (match_operand:GPR 1 "register_operand" "=&d,&d")
@@ -629,7 +629,7 @@  (define_expand "atomic_exchange<mode>"
 
 (define_insn "atomic_exchange<mode>_llsc"
   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
-	(unspec_volatile:GPR [(match_operand:GPR 1 "memory_operand" "+ZR,ZR")]
+	(unspec_volatile:GPR [(match_operand:GPR 1 "memory_operand" "+ZC,ZC")]
 	 UNSPEC_ATOMIC_EXCHANGE))
    (set (match_dup 1)
 	(unspec_volatile:GPR [(match_operand:GPR 2 "arith_operand" "I,d")]
@@ -684,7 +684,7 @@  (define_expand "atomic_fetch_add<mode>"
 
 (define_insn "atomic_fetch_add<mode>_llsc"
   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
-	(unspec_volatile:GPR [(match_operand:GPR 1 "memory_operand" "+ZR,ZR")]
+	(unspec_volatile:GPR [(match_operand:GPR 1 "memory_operand" "+ZC,ZC")]
 	 UNSPEC_ATOMIC_FETCH_OP))
    (set (match_dup 1)
 	(unspec_volatile:GPR
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 7f0426c..1ea39e2 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -2987,11 +2987,9 @@  Floating-point zero.
 An address that can be used in a non-macro load or store.
 
 @item ZC
-When compiling microMIPS code, this constraint matches a memory operand
-whose address is formed from a base register and a 12-bit offset.  These
-operands can be used for microMIPS instructions such as @code{ll} and
-@code{sc}.  When not compiling for microMIPS code, @code{ZC} is
-equivalent to @code{R}.
+A memory operand whose address is formed by a base register and offset
+that is suitable for use in instructions with the same addressing mode
+as @code{ll} and @code{sc}.
 
 @item ZD
 An address suitable for a @code{prefetch} instruction, or for any other