diff -uNra a/debian/patches/gcc-loongson3-llsc-9.2.1.diff b/debian/patches/gcc-loongson3-llsc-9.2.1.diff --- a/debian/patches/gcc-loongson3-llsc-9.2.1.diff 1970-01-01 08:00:00.000000000 +0800 +++ b/debian/patches/gcc-loongson3-llsc-9.2.1.diff 2019-11-13 10:13:34.358106516 +0800 @@ -0,0 +1,195 @@ +From patchwork Fri Nov 30 12:45:57 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [MIPS] GCC: Fix Loongson3 LLSC Errata +X-Patchwork-Submitter: Paul Hua +X-Patchwork-Id: 12860 +Message-Id: +To: gcc-patches +Cc: Matthew Fortune , syq@debian.org +Date: Fri, 30 Nov 2018 20:45:57 +0800 +From: Paul Hua +List-Id: + +In some older Loongson3 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 a) adding a +sync before ll/lld instruction, b) adding a sync +before branch target that between ll and sc. The assembler do the jobs +'a', gcc do the jobs 'b'. + +This patch also add a configure options +--with-mips-fix-loongson3-llsc=[yes|no] to enable fix-loongson3-llsc +by config. + +>From 16f0fd9e32d2098637dc0eb3e576444c48c43f22 Mon Sep 17 00:00:00 2001 +From: Chenghua Xu +Date: Fri, 30 Nov 2018 19:57:38 +0800 +Subject: [PATCH] [MIPS][GCC] Fix Loongson3 LLSC Errata. + +gcc/ + * config.gcc (supported_defaults): Add fix-loongson3-llsc + (with_fix_loongson3_llsc): Add validation. + (all_defaults): Add fix-loongson3-llsc. + * config/mips/mips.c (mips_process_sync_loop): Add sync before + branch target that between ll and sc. + * config/mips/mips.h (OPTION_DEFAULT_SPECS): Add a default for + fix-loongson3-llsc. + gcc/config/mips/mips.opt: New option. + * doc/install.texi (--with-fix-loongson3-llsc):Document the new + option. + * doc/invoke.texi (-mfix-loongson3-llsc):Document the new option. + +gcc/testsuite/ + * gcc.target/mips/fix-loongson3-llsc.c: New test. + * gcc.target/mips/mips.exp (option): Add fix-loongson3-llsc. +--- + gcc/config.gcc | 19 +++++++++++++++++-- + gcc/config/mips/mips.c | 13 +++++++++++-- + gcc/config/mips/mips.h | 4 +++- + gcc/config/mips/mips.opt | 4 ++++ + .../gcc.target/mips/fix-loongson3-llsc.c | 10 ++++++++++ + gcc/testsuite/gcc.target/mips/mips.exp | 1 + + 8 files changed, 58 insertions(+), 5 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/mips/fix-loongson3-llsc.c + +diff -uNra a/src/gcc/config/mips/mips.c b/src/gcc/config/mips/mips.c +--- a/src/gcc/config/mips/mips.c 2019-06-18 01:27:30.000000000 +0800 ++++ b/src/gcc/config/mips/mips.c 2019-10-17 03:49:50.898302293 +0800 +@@ -14155,7 +14155,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) + { +@@ -14176,6 +14176,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); +@@ -14285,13 +14289,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-01-01 20:31:55.000000000 +0800 ++++ b/src/gcc/config/mips/mips.h 2019-10-17 03:49:50.902208750 +0800 +@@ -890,7 +890,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 2019-04-08 14:37:00.000000000 +0800 ++++ b/src/gcc/config/mips/mips.opt 2019-10-17 03:49:50.902208750 +0800 +@@ -193,6 +193,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-19 00:04:11.257135917 +0800 ++++ b/src/gcc/config.gcc 2019-10-19 00:10:30.163899258 +0800 +@@ -4399,7 +4399,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) +@@ -4552,6 +4552,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*-*-*) +@@ -5080,7 +5095,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-17 03:49:50.902208750 +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 2019-01-01 20:31:55.000000000 +0800 ++++ b/src/gcc/testsuite/gcc.target/mips/mips.exp 2019-10-17 03:49:50.902208750 +0800 +@@ -281,6 +281,7 @@ + fix-r4000 + fix-r10000 + fix-vr4130 ++ fix-loongson3-llsc + gpopt + local-sdata + long-calls diff -uNra a/debian/rules.patch b/debian/rules.patch --- a/debian/rules.patch 2019-10-30 18:48:29.000000000 +0800 +++ b/debian/rules.patch 2019-11-13 10:18:50.722290406 +0800 @@ -267,6 +267,9 @@ # Has to be refreshed manually as described in the header. debian_patches += ada-changes-in-autogen-output +#loongson llsc bugfix +debian_patches += gcc-loongson3-llsc-9.2.1 + series_stamp = $(stampdir)/02-series-stamp series: $(series_stamp) $(series_stamp):