[MIPS] GAS: Fix Loongson3 LLSC errata.

Message ID CAKjxQHnw7DG_C3-WDtov3uTMoEkv5Hnw41kt+ZPM4f3WJMFGJg@mail.gmail.com
State New
Headers show
Series
  • [MIPS] GAS: Fix Loongson3 LLSC errata.
Related show

Commit Message

Paul Hua Nov. 30, 2018, 12:45 p.m.
Hi:

In some older Loongson 3A1000 processors there is a LL/SC errata that
can cause the CPU to deadlock occasionally.  The details are very
complicated. We find a way to work around this errata by adding a sync
before ll/lld instruction.

This patch also add a configure options
--enable-mips-fix-loongson3-llsc=[yes|no] to enable fix-loongson3-llsc
by config.

[MIPS] GAS: Fix Loongson3 LLSC errata.

gas/
        * NEWS: Mention -m[no-]fix-loongson3-llsc.
        * configure.ac: Add --enable-mips-fix-loongson3-llsc.
        Define DEFAULT_MIPS_FIX_LOONGSON3_LLSC.
        * config.in: Regenerated.
        * configure: Likewise.
        * config/tc-mips.c (sync_insn, mips_fix_loongson3_llsc):
        New variables.
        (options): New OPTION_FIX_LOONGSON3_LLSC,
        OPTION_NO_FIX_LOONGSON3_LLSC.
        (md_longopts): Add -m[no-]fix-loongson3-llsc.
        (md_begin): Initialize sync insn.
        (fix_loongson3_llsc): New.
        (append_insn): Call fix_loongson3_llsc.
        (md_parse_option): Handle OPTION_FIX_LOONGSON3_LLSC,
        OPTION_NO_FIX_LOONGSON3_LLSC.
        (md_show_usage): Display -m[no-]fix-loongson3-llsc.
        * doc/c-mips.texi: Document -m[no-]fix-loongson3-llsc,
        --enable-mips-fix-loongson3-llsc=[yes|no].

Comments

YunQiang Su Dec. 1, 2018, 6:17 a.m. | #1
Paul Hua <paul.hua.gm@gmail.com> 于2018年11月30日周五 下午8:46写道:
>

> Hi:

>

> In some older Loongson 3A1000 processors there is a LL/SC errata that


This problem only exists on "some older Loongson 3A1000"?
Does it exists on current 3A 3000 machines?

> can cause the CPU to deadlock occasionally.  The details are very

> complicated. We find a way to work around this errata by adding a sync

> before ll/lld instruction.

>

> This patch also add a configure options

> --enable-mips-fix-loongson3-llsc=[yes|no] to enable fix-loongson3-llsc

> by config.

>

> [MIPS] GAS: Fix Loongson3 LLSC errata.

>

> gas/

>         * NEWS: Mention -m[no-]fix-loongson3-llsc.

>         * configure.ac: Add --enable-mips-fix-loongson3-llsc.

>         Define DEFAULT_MIPS_FIX_LOONGSON3_LLSC.

>         * config.in: Regenerated.

>         * configure: Likewise.


Is configure patch needed here?
It seems been generated by some newer version autotools.

>         * config/tc-mips.c (sync_insn, mips_fix_loongson3_llsc):

>         New variables.

>         (options): New OPTION_FIX_LOONGSON3_LLSC,

>         OPTION_NO_FIX_LOONGSON3_LLSC.

>         (md_longopts): Add -m[no-]fix-loongson3-llsc.

>         (md_begin): Initialize sync insn.

>         (fix_loongson3_llsc): New.

>         (append_insn): Call fix_loongson3_llsc.

>         (md_parse_option): Handle OPTION_FIX_LOONGSON3_LLSC,

>         OPTION_NO_FIX_LOONGSON3_LLSC.

>         (md_show_usage): Display -m[no-]fix-loongson3-llsc.

>         * doc/c-mips.texi: Document -m[no-]fix-loongson3-llsc,

>         --enable-mips-fix-loongson3-llsc=[yes|no].


https://sourceware.org/ml/binutils/2018-01/msg00303.html
here is an older version of patch.
While somebody told me that it will generate a .fixup section.
What about this one?
Paul Hua Dec. 3, 2018, 10:09 a.m. | #2
> > In some older Loongson 3A1000 processors there is a LL/SC errata that

>

> This problem only exists on "some older Loongson 3A1000"?

> Does it exists on current 3A 3000 machines?


Theoretically does not exist on 3A 3000.

> > gas/

> >         * NEWS: Mention -m[no-]fix-loongson3-llsc.

> >         * configure.ac: Add --enable-mips-fix-loongson3-llsc.

> >         Define DEFAULT_MIPS_FIX_LOONGSON3_LLSC.

> >         * config.in: Regenerated.

> >         * configure: Likewise.

>

> Is configure patch needed here?

> It seems been generated by some newer version autotools.


Yes, We change the configure.ac file, so regenerated.

> >         * config/tc-mips.c (sync_insn, mips_fix_loongson3_llsc):

> >         New variables.

> >         (options): New OPTION_FIX_LOONGSON3_LLSC,

> >         OPTION_NO_FIX_LOONGSON3_LLSC.

> >         (md_longopts): Add -m[no-]fix-loongson3-llsc.

> >         (md_begin): Initialize sync insn.

> >         (fix_loongson3_llsc): New.

> >         (append_insn): Call fix_loongson3_llsc.

> >         (md_parse_option): Handle OPTION_FIX_LOONGSON3_LLSC,

> >         OPTION_NO_FIX_LOONGSON3_LLSC.

> >         (md_show_usage): Display -m[no-]fix-loongson3-llsc.

> >         * doc/c-mips.texi: Document -m[no-]fix-loongson3-llsc,

> >         --enable-mips-fix-loongson3-llsc=[yes|no].

>

> https://sourceware.org/ml/binutils/2018-01/msg00303.html

> here is an older version of patch.

> While somebody told me that it will generate a .fixup section.

> What about this one?

Both patch does not generate a .fixup section.

Patch

From 974dd8aa61ff59437d1b88d744fb5a2e8f10f8e2 Mon Sep 17 00:00:00 2001
From: Chenghua Xu <xuchenghua@loongson.cn>
Date: Fri, 30 Nov 2018 19:41:40 +0800
Subject: [PATCH] [MIPS] GAS: Fix Loongson3 LLSC errata.

gas/
	* NEWS: Mention -m[no-]fix-loongson3-llsc.
	* configure.ac: Add --enable-mips-fix-loongson3-llsc.
	Define DEFAULT_MIPS_FIX_LOONGSON3_LLSC.
	* config.in: Regenerated.
	* configure: Likewise.
	* config/tc-mips.c (sync_insn, mips_fix_loongson3_llsc):
	New variables.
	(options): New OPTION_FIX_LOONGSON3_LLSC,
	OPTION_NO_FIX_LOONGSON3_LLSC.
	(md_longopts): Add -m[no-]fix-loongson3-llsc.
	(md_begin): Initialize sync insn.
	(fix_loongson3_llsc): New.
	(append_insn): Call fix_loongson3_llsc.
	(md_parse_option): Handle OPTION_FIX_LOONGSON3_LLSC,
	OPTION_NO_FIX_LOONGSON3_LLSC.
	(md_show_usage): Display -m[no-]fix-loongson3-llsc.
	* doc/c-mips.texi: Document -m[no-]fix-loongson3-llsc,
	--enable-mips-fix-loongson3-llsc=[yes|no].
---
 gas/NEWS             |  4 ++++
 gas/config.in        |  3 +++
 gas/config/tc-mips.c | 56 +++++++++++++++++++++++++++++++++++++++++++-
 gas/configure        | 51 +++++++++++++++++++++++++++++++++-------
 gas/configure.ac     | 18 ++++++++++++++
 gas/doc/c-mips.texi  |  7 ++++++
 6 files changed, 130 insertions(+), 9 deletions(-)

diff --git a/gas/NEWS b/gas/NEWS
index 26f78b08c6..83634192d1 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,4 +1,8 @@ 
 -*- text -*-
+* For MIPS, Add -m[no-]fix-loongson3-llsc option to fix (or not) Loongson3 LLSC
+  Errata.  Add a --enable-mips-fix-loongson3-llsc=[yes|no] configure time option
+  to set the default behavior. Set the default if the configure option is not used
+  to "no".
 
 * Add -mvexwig=[0|1] option to x86 assembler to control encoding of
   VEX.W-ignored (WIG) VEX instructions.
diff --git a/gas/config.in b/gas/config.in
index 9c15a070a3..8a8a4c0568 100644
--- a/gas/config.in
+++ b/gas/config.in
@@ -50,6 +50,9 @@ 
 /* Define to 1 if you want to generate x86 relax relocations by default. */
 #undef DEFAULT_GENERATE_X86_RELAX_RELOCATIONS
 
+/* Define to 1 if you want to fix Loongson3 LLSC Errata by default. */
+#undef DEFAULT_MIPS_FIX_LOONGSON3_LLSC
+
 /* Define to 1 if you want to generate GNU x86 used ISA and feature properties
    by default. */
 #undef DEFAULT_X86_USED_NOTE
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 918525b4e9..cc5dd52c69 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -808,6 +808,9 @@  static struct mips_cl_insn mips16_nop_insn;
 static struct mips_cl_insn micromips_nop16_insn;
 static struct mips_cl_insn micromips_nop32_insn;
 
+/* Sync instructions used by insert sync.  */
+static struct mips_cl_insn sync_insn;
+
 /* The appropriate nop for the current mode.  */
 #define NOP_INSN (mips_opts.mips16					\
 		  ? &mips16_nop_insn					\
@@ -939,6 +942,9 @@  static int mips_fix_rm7000;
 /* ...likewise -mfix-cn63xxp1 */
 static bfd_boolean mips_fix_cn63xxp1;
 
+/* ...likewise -mfix-loongson3-llsc.  */
+static bfd_boolean mips_fix_loongson3_llsc = DEFAULT_MIPS_FIX_LOONGSON3_LLSC;
+
 /* We don't relax branches by default, since this causes us to expand
    `la .l2 - .l1' if there's a branch between .l1 and .l2, because we
    fail to compute the offset before expanding the macro to the most
@@ -1478,6 +1484,8 @@  enum options
     OPTION_NO_FIX_24K,
     OPTION_FIX_RM7000,
     OPTION_NO_FIX_RM7000,
+    OPTION_FIX_LOONGSON3_LLSC,
+    OPTION_NO_FIX_LOONGSON3_LLSC,
     OPTION_FIX_LOONGSON2F_JUMP,
     OPTION_NO_FIX_LOONGSON2F_JUMP,
     OPTION_FIX_LOONGSON2F_NOP,
@@ -1622,6 +1630,8 @@  struct option md_longopts[] =
   {"mfix7000", no_argument, NULL, OPTION_M7000_HILO_FIX},
   {"no-fix-7000", no_argument, NULL, OPTION_MNO_7000_HILO_FIX},
   {"mno-fix7000", no_argument, NULL, OPTION_MNO_7000_HILO_FIX},
+  {"mfix-loongson3-llsc",   no_argument, NULL, OPTION_FIX_LOONGSON3_LLSC},
+  {"mno-fix-loongson3-llsc", no_argument, NULL, OPTION_NO_FIX_LOONGSON3_LLSC},
   {"mfix-loongson2f-jump", no_argument, NULL, OPTION_FIX_LOONGSON2F_JUMP},
   {"mno-fix-loongson2f-jump", no_argument, NULL, OPTION_NO_FIX_LOONGSON2F_JUMP},
   {"mfix-loongson2f-nop", no_argument, NULL, OPTION_FIX_LOONGSON2F_NOP},
@@ -3670,6 +3680,10 @@  md_begin (void)
 		nop_insn.insn_opcode = LOONGSON2F_NOP_INSN;
 	      nop_insn.fixed_p = 1;
 	    }
+	  if (sync_insn.insn_mo == NULL && strcmp (name, "sync") == 0)
+	    {
+	      create_insn (&sync_insn, mips_opcodes + i);
+	    }
 	  ++i;
 	}
       while ((i < NUMOPCODES) && !strcmp (mips_opcodes[i].name, name));
@@ -6851,6 +6865,22 @@  fix_loongson2f (struct mips_cl_insn * ip)
     fix_loongson2f_jump (ip);
 }
 
+/* Fix loongson3 llsc errata: Insert sync before ll/lld. */
+static void
+fix_loongson3_llsc (struct mips_cl_insn * ip)
+{
+  gas_assert (!HAVE_CODE_COMPRESSION);
+
+  /* Skip if there is a sync before ll/lld.  */
+  if ((strcmp (ip->insn_mo->name, "ll") == 0
+       || strcmp (ip->insn_mo->name, "lld") == 0)
+      && (strcmp (history[0].insn_mo->name, "sync") != 0))
+    {
+      add_fixed_insn (&sync_insn);
+      insert_into_history (0, 1, &sync_insn);
+    }
+}
+
 /* IP is a branch that has a delay slot, and we need to fill it
    automatically.   Return true if we can do that by swapping IP
    with the previous instruction.
@@ -7308,6 +7338,9 @@  append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
   if (mips_fix_loongson2f && !HAVE_CODE_COMPRESSION)
     fix_loongson2f (ip);
 
+  if (mips_fix_loongson3_llsc && !HAVE_CODE_COMPRESSION)
+    fix_loongson3_llsc (ip);
+
   file_ase_mips16 |= mips_opts.mips16;
   file_ase_micromips |= mips_opts.micromips;
 
@@ -14723,6 +14756,14 @@  md_parse_option (int c, const char *arg)
       mips_fix_rm7000 = 0;
       break;
 
+    case OPTION_FIX_LOONGSON3_LLSC:
+      mips_fix_loongson3_llsc = TRUE;
+      break;
+
+    case OPTION_NO_FIX_LOONGSON3_LLSC:
+      mips_fix_loongson3_llsc = FALSE;
+      break;
+
     case OPTION_FIX_LOONGSON2F_JUMP:
       mips_fix_loongson2f_jump = TRUE;
       break;
@@ -20120,7 +20161,20 @@  MIPS options:\n\
 -mno-insn32		generate all microMIPS instructions\n"));
   fprintf (stream, _("\
 -mfix-loongson2f-jump	work around Loongson2F JUMP instructions\n\
--mfix-loongson2f-nop	work around Loongson2F NOP errata\n\
+-mfix-loongson2f-nop	work around Loongson2F NOP errata\n"));
+  fprintf (stream, _("\
+-mfix-loongson3-llsc	"));
+if (DEFAULT_MIPS_FIX_LOONGSON3_LLSC)
+{
+  fprintf (stream, _("(default: -mfix-loongson3-llsc)\n"));
+}
+else
+{
+  fprintf (stream, _("(default: -mno-fix-loongson3-llsc)\n"));
+}
+  fprintf (stream, _("\
+			work around Loongson3 LLSC errata\n"));
+  fprintf (stream, _("\
 -mfix-vr4120		work around certain VR4120 errata\n\
 -mfix-vr4130		work around VR4130 mflo/mfhi errata\n\
 -mfix-24k		insert a nop after ERET and DERET instructions\n\
diff --git a/gas/configure b/gas/configure
index 27b6e8e8c6..e369afd97a 100755
--- a/gas/configure
+++ b/gas/configure
@@ -770,6 +770,7 @@  infodir
 docdir
 oldincludedir
 includedir
+runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -809,6 +810,7 @@  enable_x86_relax_relocations
 enable_elf_stt_common
 enable_generate_build_notes
 enable_x86_used_note
+enable_mips_fix_loongson3_llsc
 enable_werror
 enable_build_warnings
 with_cpu
@@ -865,6 +867,7 @@  datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1117,6 +1120,15 @@  do
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1254,7 +1266,7 @@  fi
 for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-		libdir localedir mandir
+		libdir localedir mandir runstatedir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -1407,6 +1419,7 @@  Fine tuning of the installation directories:
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
@@ -1471,6 +1484,8 @@  Optional Features:
                           generate GNU Build notes if none are provided by the
                           input
   --enable-x86-used-note  generate GNU x86 used ISA and feature properties
+  --enable-mips-fix-loongson3-llsc
+                          enable MIPS fix Loongson3 LLSC errata
   --enable-werror         treat compile warnings as errors
   --enable-build-warnings enable build-time compiler warnings
   --disable-nls           do not use Native Language Support
@@ -11337,7 +11352,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11340 "configure"
+#line 11355 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11443,7 +11458,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11446 "configure"
+#line 11461 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11830,7 +11845,7 @@  else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -11876,7 +11891,7 @@  else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -11900,7 +11915,7 @@  rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -11945,7 +11960,7 @@  else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -11969,7 +11984,7 @@  rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -12125,6 +12140,17 @@  if test "${enable_x86_used_note+set}" = set; then :
 esac
 fi
 
+# Decide if the MIPS assembler should default to enable MIPS fix Loongson3
+# LLSC errata.
+ac_default_mips_fix_loongson3_llsc=unset
+# Provide a configuration option to override the default.
+# Check whether --enable-mips-fix-loongson3-llsc was given.
+if test "${enable_mips_fix_loongson3_llsc+set}" = set; then :
+  enableval=$enable_mips_fix_loongson3_llsc; case "${enableval}" in
+  yes)  ac_default_mips_fix_loongson3_llsc=1 ;;
+  no)   ac_default_mips_fix_loongson3_llsc=0 ;;
+esac
+fi
 
 using_cgen=no
 
@@ -13102,6 +13128,15 @@  cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+if test ${ac_default_mips_fix_loongson3_llsc} = unset; then
+  ac_default_mips_fix_loongson3_llsc=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_MIPS_FIX_LOONGSON3_LLSC $ac_default_mips_fix_loongson3_llsc
+_ACEOF
+
+
 if test x$ac_default_compressed_debug_sections = xyes ; then
 
 $as_echo "#define DEFAULT_FLAG_COMPRESS_DEBUG 1" >>confdefs.h
diff --git a/gas/configure.ac b/gas/configure.ac
index 93faa4113d..28b0a66f90 100644
--- a/gas/configure.ac
+++ b/gas/configure.ac
@@ -125,6 +125,17 @@  AC_ARG_ENABLE(x86-used-note,
   no)   ac_default_generate_x86_used_note=0 ;;
 esac])dnl
 
+# Decide if the MIPS assembler should default to enable MIPS fix Loongson3
+# LLSC errata.
+ac_default_mips_fix_loongson3_llsc=unset
+# Provide a configuration option to override the default.
+AC_ARG_ENABLE(mips-fix-loongson3-llsc,
+	      AS_HELP_STRING([--enable-mips-fix-loongson3-llsc],
+	      [enable MIPS fix Loongson3 LLSC errata]),
+[case "${enableval}" in
+  yes)  ac_default_mips_fix_loongson3_llsc=1 ;;
+  no)   ac_default_mips_fix_loongson3_llsc=0 ;;
+esac])dnl
 
 using_cgen=no
 
@@ -663,6 +674,13 @@  AC_DEFINE_UNQUOTED(DEFAULT_X86_USED_NOTE,
   [Define to 1 if you want to generate GNU x86 used ISA and feature
    properties by default.])
 
+if test ${ac_default_mips_fix_loongson3_llsc} = unset; then
+  ac_default_mips_fix_loongson3_llsc=0
+fi
+AC_DEFINE_UNQUOTED(DEFAULT_MIPS_FIX_LOONGSON3_LLSC,
+  $ac_default_mips_fix_loongson3_llsc,
+  [Define to 1 if you want to fix Loongson3 LLSC Errata by default.])
+
 if test x$ac_default_compressed_debug_sections = xyes ; then
   AC_DEFINE(DEFAULT_FLAG_COMPRESS_DEBUG, 1, [Define if you want compressed debug sections by default.])
 fi
diff --git a/gas/doc/c-mips.texi b/gas/doc/c-mips.texi
index 7751ce01d6..c779cef295 100644
--- a/gas/doc/c-mips.texi
+++ b/gas/doc/c-mips.texi
@@ -308,6 +308,13 @@  Replace nops by @code{or at,at,zero} to work around the Loongson2F
 deadlock.  The issue has been solved in later Loongson2F batches, but
 this fix has no side effect to them.
 
+@item -mfix-loongson3-llsc
+@itemx -mno-fix-loongson3-llsc
+Insert @samp{sync} before @samp{ll} and @samp{lld} to work around 
+Loongson3 LLSC errata.  Without it, under extrame cases, the CPU might
+deadlock. The default can be controlled by the
+@option{--enable-mips-fix-loongson3-llsc=[yes|no]} configure option.
+
 @item -mfix-vr4120
 @itemx -mno-fix-vr4120
 Insert nops to work around certain VR4120 errata.  This option is
-- 
2.19.1