diff -uNra debian1/patches/gcc-loongson3-llsc-8.3.0.diff debian/patches/gcc-loongson3-llsc-8.3.0.diff
--- debian1/patches/gcc-loongson3-llsc-8.3.0.diff	1970-01-01 08:00:00.000000000 +0800
+++ debian/patches/gcc-loongson3-llsc-8.3.0.diff	2019-11-13 10:24:41.064811907 +0800
@@ -0,0 +1,139 @@
+diff -uNra a/src/gcc/config/mips/mips.c b/src/gcc/config/mips/mips.c
+--- a/src/gcc/config/mips/mips.c	2018-03-01 19:37:35.000000000 +0800
++++ b/src/gcc/config/mips/mips.c	2019-10-15 04:07:39.550356089 +0800
+@@ -14097,7 +14097,7 @@
+   mips_multi_start ();
+ 
+   /* Output the release side of the memory barrier.  */
+-  if (need_atomic_barrier_p (model, true))
++  if (need_atomic_barrier_p (model, true) && !FIX_LOONGSON3_LLSC)
+     {
+       if (required_oldval == 0 && TARGET_OCTEON)
+ 	{
+@@ -14118,6 +14118,10 @@
+   /* Output the branch-back label.  */
+   mips_multi_add_label ("1:");
+ 
++  /* Loongson3 target need sync before ll/lld.  */
++  if (need_atomic_barrier_p (model,  true) && FIX_LOONGSON3_LLSC)
++    mips_multi_add_insn ("sync", NULL);
++
+   /* OLDVAL = *MEM.  */
+   mips_multi_add_insn (is_64bit_p ? "lld\t%0,%1" : "ll\t%0,%1",
+ 		       oldval, mem, NULL);
+@@ -14227,13 +14231,18 @@
+     mips_multi_add_insn ("li\t%0,1", cmp, NULL);
+ 
+   /* Output the acquire side of the memory barrier.  */
+-  if (TARGET_SYNC_AFTER_SC && need_atomic_barrier_p (model, false))
++  if (TARGET_SYNC_AFTER_SC && need_atomic_barrier_p (model, false)
++      && !FIX_LOONGSON3_LLSC)
+     mips_multi_add_insn ("sync", NULL);
+ 
+   /* Output the exit label, if needed.  */
+   if (required_oldval)
+     mips_multi_add_label ("2:");
+ 
++  /* Loongson3 need a sync before branch target that between ll and sc.  */
++  if (FIX_LOONGSON3_LLSC)
++    mips_multi_add_insn ("sync", NULL);
++
+ #undef READ_OPERAND
+ }
+ 
+diff -uNra a/src/gcc/config/mips/mips.h b/src/gcc/config/mips/mips.h
+--- a/src/gcc/config/mips/mips.h	2019-10-15 03:00:17.357126209 +0800
++++ b/src/gcc/config/mips/mips.h	2019-10-15 04:07:39.558169003 +0800
+@@ -875,7 +875,9 @@
+   {"mips-plt", "%{!mplt:%{!mno-plt:-m%(VALUE)}}" }, \
+   {"synci", "%{!msynci:%{!mno-synci:-m%(VALUE)}}" },			\
+   {"lxc1-sxc1", "%{!mlxc1-sxc1:%{!mno-lxc1-sxc1:-m%(VALUE)}}" }, \
+-  {"madd4", "%{!mmadd4:%{!mno-madd4:-m%(VALUE)}}" } \
++  {"madd4", "%{!mmadd4:%{!mno-madd4:-m%(VALUE)}}" },  \
++  {"fix-loongson3-llsc", "%{!mfix-loongson3-llsc:   \
++			  %{!mno-fix-loongson3-llsc:-m%(VALUE)}}" }
+ 
+ /* A spec that infers the:
+    -mnan=2008 setting from a -mips argument,
+diff -uNra a/src/gcc/config/mips/mips.opt b/src/gcc/config/mips/mips.opt
+--- a/src/gcc/config/mips/mips.opt	2018-01-03 18:03:58.000000000 +0800
++++ b/src/gcc/config/mips/mips.opt	2019-10-15 04:07:39.565981916 +0800
+@@ -189,6 +189,10 @@
+ Target Report Var(TARGET_4300_MUL_FIX)
+ Work around an early 4300 hardware bug.
+ 
++mfix-loongson3-llsc
++Target Report Var(FIX_LOONGSON3_LLSC)
++Work around an Loongson3 llsc errata.
++
+ mfp-exceptions
+ Target Report Var(TARGET_FP_EXCEPTIONS) Init(1)
+ FP exceptions are enabled.
+diff -uNra a/src/gcc/config.gcc b/src/gcc/config.gcc
+--- a/src/gcc/config.gcc	2019-10-15 03:00:17.357126209 +0800
++++ b/src/gcc/config.gcc	2019-10-15 04:07:39.499572153 +0800
+@@ -4195,7 +4195,7 @@
+ 		;;
+ 
+ 	mips*-*-*)
+-		supported_defaults="abi arch arch_32 arch_64 float fpu nan fp_32 odd_spreg_32 tune tune_32 tune_64 divide llsc mips-plt synci lxc1-sxc1 madd4"
++		supported_defaults="abi arch arch_32 arch_64 float fpu nan fp_32 odd_spreg_32 tune tune_32 tune_64 divide llsc mips-plt synci lxc1-sxc1 madd4 fix-loongson3-llsc"
+ 
+ 		case ${with_float} in
+ 		"" | soft | hard)
+@@ -4348,6 +4348,21 @@
+ 			exit 1
+ 			;;
+ 		esac
++
++		case ${with_fix_loongson3_llsc} in
++		yes)
++			with_fix_loongson3_llsc=fix-loongson3-llsc
++			;;
++		no)
++			with_fix_loongson3_llsc=no-fix-loongson3-llsc
++			;;
++		"")
++			;;
++		*)
++			echo "Unknown fix-loongson3-llsc type used in --with-fix-loongson3-llsc" 1>&2
++			exit 1
++			;;
++		esac
+ 		;;
+ 
+ 	nds32*-*-*)
+@@ -4840,7 +4855,7 @@
+ esac
+ 
+ t=
+-all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu nan fp_32 odd_spreg_32 divide llsc mips-plt synci tls lxc1-sxc1 madd4"
++all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu nan fp_32 odd_spreg_32 divide llsc mips-plt synci tls lxc1-sxc1 madd4 fix-loongson3-llsc"
+ for option in $all_defaults
+ do
+ 	eval "val=\$with_"`echo $option | sed s/-/_/g`
+diff -uNra a/src/gcc/testsuite/gcc.target/mips/fix-loongson3-llsc.c b/src/gcc/testsuite/gcc.target/mips/fix-loongson3-llsc.c
+--- a/src/gcc/testsuite/gcc.target/mips/fix-loongson3-llsc.c	1970-01-01 08:00:00.000000000 +0800
++++ b/src/gcc/testsuite/gcc.target/mips/fix-loongson3-llsc.c	2019-10-15 04:07:39.601140026 +0800
+@@ -0,0 +1,10 @@
++/* { dg-do compile } */
++/* { dg-options "-mfix-loongson3-llsc" } */
++
++NOMIPS16 int foo (int *v)
++{
++  return  __sync_val_compare_and_swap (v, 0, 1);
++}
++
++/* { dg-final { scan-assembler "1:\n\tsync\n\tll" } } */
++/* { dg-final { scan-assembler "2:\n\tsync\n" } } */
+diff -uNra a/src/gcc/testsuite/gcc.target/mips/mips.exp b/src/gcc/testsuite/gcc.target/mips/mips.exp
+--- a/src/gcc/testsuite/gcc.target/mips/mips.exp	2018-01-03 18:03:58.000000000 +0800
++++ b/src/gcc/testsuite/gcc.target/mips/mips.exp	2019-10-15 04:07:39.605046483 +0800
+@@ -281,6 +281,7 @@
+     fix-r4000
+     fix-r10000
+     fix-vr4130
++    fix-loongson3-llsc
+     gpopt
+     local-sdata
+     long-calls
diff -uNra debian1/rules.patch debian/rules.patch
--- debian1/rules.patch	2019-11-13 08:54:34.000000000 +0800
+++ debian/rules.patch	2019-11-13 10:27:18.358185548 +0800
@@ -308,6 +308,9 @@
 # Has to be refreshed manually as described in the header.
 debian_patches += ada-changes-in-autogen-output
 
+#loongson3 llsc bugfix
+debian_patches += gcc-loongson3-llsc-8.3.0
+
 series_stamp = $(stampdir)/02-series-stamp
 series: $(series_stamp)
 $(series_stamp):
