diff --git a/gcc/config.in b/gcc/config.in
index 99fd2d89fe3..ce1d073833f 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -2356,6 +2356,12 @@
 #endif
 
 
+/* Define if assembler supports %reloc. */
+#ifndef USED_FOR_TARGET
+#undef MIPS_EXPLICIT_RELOCS
+#endif
+
+
 /* Define if host mkdir takes a single argument. */
 #ifndef USED_FOR_TARGET
 #undef MKDIR_TAKES_ONE_ARG
diff --git a/gcc/config/mips/mips-opts.h b/gcc/config/mips/mips-opts.h
index 57bdbdfa721..4b0c2c09a3d 100644
--- a/gcc/config/mips/mips-opts.h
+++ b/gcc/config/mips/mips-opts.h
@@ -53,4 +53,11 @@ enum mips_cb_setting {
   MIPS_CB_OPTIMAL,
   MIPS_CB_ALWAYS
 };
+
+/* Enumerates the setting of the -mexplicit-relocs= option.  */
+enum mips_explicit_relocs {
+  MIPS_EXPLICIT_RELOCS_NONE,
+  MIPS_EXPLICIT_RELOCS_BASE,
+  MIPS_EXPLICIT_RELOCS_PCREL
+};
 #endif
diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index 30e99811ff6..68e2ae8d8fa 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -20033,8 +20033,6 @@ mips_set_compression_mode (unsigned int compression_mode)
 	 call.  */
       flag_move_loop_invariants = 0;
 
-      target_flags |= MASK_EXPLICIT_RELOCS;
-
       /* Experiments suggest we get the best overall section-anchor
 	 results from using the range of an unextended LW or SW.  Code
 	 that makes heavy use of byte or short accesses can do better
@@ -20064,6 +20062,9 @@ mips_set_compression_mode (unsigned int compression_mode)
 
       if (TARGET_MSA)
 	sorry ("MSA MIPS16 code");
+
+      if (!TARGET_EXPLICIT_RELOCS)
+	sorry ("MIPS16 requires %<-mexplicit-relocs%>");
     }
   else
     {
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 8768933ba37..7145d23c650 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -145,6 +145,14 @@ struct mips_cpu_info {
 		      || TARGET_MICROMIPS)		\
 		     && mips_cb != MIPS_CB_NEVER)
 
+/* True if assembler support %gp_rel etc.  */
+#define TARGET_EXPLICIT_RELOCS \
+  (mips_opt_explicit_relocs >= MIPS_EXPLICIT_RELOCS_BASE)
+
+/* True if assembler support %pcrel_hi/%pcrel_lo.  */
+#define TARGET_EXPLICIT_RELOCS_PCREL \
+  (mips_opt_explicit_relocs >= MIPS_EXPLICIT_RELOCS_PCREL)
+
 /* True if the output file is marked as ".abicalls; .option pic0"
    (-call_nonpic).  */
 #define TARGET_ABICALLS_PIC0 \
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index e8b411a8ffe..ce36942aabe 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -145,9 +145,30 @@ meva
 Target Var(TARGET_EVA)
 Use Enhanced Virtual Addressing instructions.
 
+Enum
+Name(mips_explicit_relocs) Type(int)
+The code model option names for -mexplicit-relocs:
+
+EnumValue
+Enum(mips_explicit_relocs) String(none) Value(MIPS_EXPLICIT_RELOCS_NONE)
+
+EnumValue
+Enum(mips_explicit_relocs) String(base) Value(MIPS_EXPLICIT_RELOCS_BASE)
+
+EnumValue
+Enum(mips_explicit_relocs) String(pcrel) Value(MIPS_EXPLICIT_RELOCS_PCREL)
+
+mexplicit-relocs=
+Target RejectNegative Joined Enum(mips_explicit_relocs) Var(mips_opt_explicit_relocs) Init(MIPS_EXPLICIT_RELOCS)
+Use %reloc() assembly operators.
+
 mexplicit-relocs
-Target Mask(EXPLICIT_RELOCS)
-Use NewABI-style %reloc() assembly operators.
+Target RejectNegative Alias(mexplicit-relocs=,base)
+Use %reloc() assembly operators (for backward compatibility).
+
+mno-explicit-relocs
+Target RejectNegative Alias(mexplicit-relocs=,none)
+Don't use %reloc() assembly operators (for backward compatibility).
 
 mextern-sdata
 Target Var(TARGET_EXTERN_SDATA) Init(1)
diff --git a/gcc/configure b/gcc/configure
index 4acb254d830..578c72da70a 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -30351,8 +30351,41 @@ fi
     ;;
 
   mips*-*-*)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for explicit relocation support" >&5
-$as_echo_n "checking assembler for explicit relocation support... " >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for explicit relocation support: %pcrel_hi/%pcrel_lo" >&5
+$as_echo_n "checking assembler for explicit relocation support: %pcrel_hi/%pcrel_lo... " >&6; }
+if ${gcc_cv_as_mips_explicit_relocs_pcrel+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcc_cv_as_mips_explicit_relocs_pcrel=no
+  if test x$gcc_cv_as != x; then
+    $as_echo '	lui $4,%pcrel_hi(foo)' > conftest.s
+    if { ac_try='$gcc_cv_as $gcc_cv_as_flags  -o conftest.o conftest.s >&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+    then
+	gcc_cv_as_mips_explicit_relocs_pcrel=yes
+    else
+      echo "configure: failed program was" >&5
+      cat conftest.s >&5
+    fi
+    rm -f conftest.o conftest.s
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_mips_explicit_relocs_pcrel" >&5
+$as_echo "$gcc_cv_as_mips_explicit_relocs_pcrel" >&6; }
+if test $gcc_cv_as_mips_explicit_relocs_pcrel = yes; then
+
+$as_echo "#define MIPS_EXPLICIT_RELOCS MIPS_EXPLICIT_RELOCS_PCREL" >>confdefs.h
+
+fi
+
+
+    if test x$gcc_cv_as_mips_explicit_relocs_pcrel = xno; then \
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for explicit relocation support: %gp_rel" >&5
+$as_echo_n "checking assembler for explicit relocation support: %gp_rel... " >&6; }
 if ${gcc_cv_as_mips_explicit_relocs+:} false; then :
   $as_echo_n "(cached) " >&6
 else
@@ -30377,12 +30410,18 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_mips_explicit_relocs" >&5
 $as_echo "$gcc_cv_as_mips_explicit_relocs" >&6; }
 if test $gcc_cv_as_mips_explicit_relocs = yes; then
-  if test x$target_cpu_default = x
-       then target_cpu_default=MASK_EXPLICIT_RELOCS
-       else target_cpu_default="($target_cpu_default)|MASK_EXPLICIT_RELOCS"
-       fi
+
+$as_echo "#define MIPS_EXPLICIT_RELOCS MIPS_EXPLICIT_RELOCS_BASE" >>confdefs.h
+
 fi
 
+    fi
+
+    if test x$gcc_cv_as_mips_explicit = xno; then \
+
+$as_echo "#define MIPS_EXPLICIT_RELOCS MIPS_EXPLICIT_RELOCS_NONE" >>confdefs.h
+
+    fi
 
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for -mno-shared support" >&5
 $as_echo_n "checking assembler for -mno-shared support... " >&6; }
diff --git a/gcc/configure.ac b/gcc/configure.ac
index d2ed14496c1..5cc9338bec4 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -5241,13 +5241,24 @@ LCF0:
     ;;
 
   mips*-*-*)
-    gcc_GAS_CHECK_FEATURE([explicit relocation support],
+    gcc_GAS_CHECK_FEATURE([explicit relocation support: %pcrel_hi/%pcrel_lo],
+      gcc_cv_as_mips_explicit_relocs_pcrel,,
+[	lui $4,%pcrel_hi(foo)],,
+      [AC_DEFINE(MIPS_EXPLICIT_RELOCS, MIPS_EXPLICIT_RELOCS_PCREL,
+		 [Define if assembler supports %pcrel_hi/%pcrel_lo.])])
+
+    if test x$gcc_cv_as_mips_explicit_relocs_pcrel = xno; then \
+    gcc_GAS_CHECK_FEATURE([explicit relocation support: %gp_rel],
       gcc_cv_as_mips_explicit_relocs,,
 [	lw $4,%gp_rel(foo)($4)],,
-      [if test x$target_cpu_default = x
-       then target_cpu_default=MASK_EXPLICIT_RELOCS
-       else target_cpu_default="($target_cpu_default)|MASK_EXPLICIT_RELOCS"
-       fi])
+      [AC_DEFINE(MIPS_EXPLICIT_RELOCS, MIPS_EXPLICIT_RELOCS_BASE,
+		 [Define if assembler supports %reloc.])])
+    fi
+
+    if test x$gcc_cv_as_mips_explicit = xno; then \
+      AC_DEFINE(MIPS_EXPLICIT_RELOCS, MIPS_EXPLICIT_RELOCS_NONE,
+		[Define if assembler supports %reloc.])
+    fi
 
     gcc_GAS_CHECK_FEATURE([-mno-shared support],
       gcc_cv_as_mips_no_shared,[-mno-shared], [nop],,
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 43fd3c3a3cd..c4a22752c1c 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1137,6 +1137,7 @@ Objective-C and Objective-C++ Dialects}.
 -mcode-readable=@var{setting}
 -msplit-addresses  -mno-split-addresses
 -mexplicit-relocs  -mno-explicit-relocs
+-mexplicit-relocs=@var{release}
 -mcheck-zero-division  -mno-check-zero-division
 -mdivide-traps  -mdivide-breaks
 -mload-store-pairs  -mno-load-store-pairs
@@ -28693,6 +28694,21 @@ branch to be used if one is available in the current ISA and the delay
 slot is successfully filled.  If the delay slot is not filled, a compact
 branch will be chosen if one is available.
 
+@opindex mexplicit-relocs=none
+@opindex mexplicit-relocs=base
+@opindex mexplicit-relocs=pcrel
+@item -mexplicit-relocs=none
+@itemx -mexplicit-relocs=base
+@itemx -mexplicit-relocs=pcrel
+@itemx -mexplicit-relocs
+@itemx -mno-explicit-relocs
+These options control whether explicit relocs (such as %gp_rel) are used.
+The default value depends on the version of GAS when GCC itself was built.
+
+The @code{base} explicit-relocs support introdunced into GAS in 2001.
+The @code{pcrel} explicit-relocs support introdunced into GAS in 2014,
+which supports @code{%pcrel_hi} and @code{%pcrel_lo}.
+
 @opindex mfp-exceptions
 @item -mfp-exceptions
 @itemx -mno-fp-exceptions
