From patchwork Fri Dec 14 14:46:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: YunQiang Su X-Patchwork-Id: 1013570 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-492490-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=debian.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="bIkDP6dW"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43GYLL0YtRz9s3q for ; Sat, 15 Dec 2018 01:47:37 +1100 (AEDT) Received: (qmail 122631 invoked by alias); 14 Dec 2018 14:47:32 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 122609 invoked by uid 89); 14 Dec 2018 14:47:31 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=acquire, mabi, Report, sk:fno-del X-HELO: mail-pl1-f193.google.com Received: from mail-pl1-f193.google.com (HELO mail-pl1-f193.google.com) (209.85.214.193) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 14 Dec 2018 14:47:27 +0000 Received: by mail-pl1-f193.google.com with SMTP id 101so2841830pld.6 for ; Fri, 14 Dec 2018 06:47:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=nw+Gtn7Gljy/WeWmsxdakbpdQWrZiM6Q+1+Ag7lZpvs=; b=bIkDP6dWjtjtX07R3Ti+rvghvIgXYTy1GFPquVyyWfbZr57wNMzQQfFb31XwCJpMB0 mfZqx+RO98ETMdRDQoTdPyGTtkDmcCodJzekrqE0lamtw2yfP4T72bNReqKXIWqehTOz 0kFQDqdSIaHggRuuzzuEplHMuv3GDeNMESADnRXX4lv/rXy4DWVksx5bNxBB+dEy70gR Tz/7MW7MxoB/hPTR7/FyHu3ZIKAJWHDwjWU7owKhb5HG+a6zygQkUlIh/0ufGiISp48/ AZlifh+4Gol/voNL4FDTtnqcPTWePZHOhBThyOu9MIODp0WK6ieOxVdDe5Yzm2slPBxE u9YQ== Received: from localhost.localdomain ([47.74.12.188]) by smtp.gmail.com with ESMTPSA id c13sm15216508pfe.93.2018.12.14.06.47.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 14 Dec 2018 06:47:24 -0800 (PST) Sender: YunQiang Su From: YunQiang Su To: gcc-patches@gcc.gnu.org Cc: rfuhler@wavecomp.com, Paul Hua Subject: [PATCH v2] [MIPS] GCC: Fix Loongson3 LLSC Errata Date: Fri, 14 Dec 2018 22:46:57 +0800 Message-Id: <20181214144657.3683-1-syq@debian.org> MIME-Version: 1.0 From: Paul Hua 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 add an option '-mfix-loongson3-llsc' option, and it will also call 'as' with the same option. So if 'as' doesn't support this option, an error will happen. The macro '__mips_fix_loongson3_llsc' is predefined, when this option is enabled, as some program, like linux kernel will need to aware this option is used. This patch also add a configure options --with-mips-fix-loongson3-llsc=[yes|no] to enable fix-loongson3-llsc by config. v1 -> v2: * Predefine __mips_fix_loongson3_llsc. * Add to ASM_SPECS. 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. (ASM_SPECS): Add a default for fix-loongson3-llsc. (TARGET_CPU_CPP_BUILTINS): Predefine __mips_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 | 7 ++++++- gcc/config/mips/mips.opt | 4 ++++ .../gcc.target/mips/fix-loongson3-llsc.c | 10 ++++++++++ gcc/testsuite/gcc.target/mips/mips.exp | 1 + 6 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/mips/fix-loongson3-llsc.c diff --git a/gcc/config.gcc b/gcc/config.gcc index 3122a0ce2..72b94b1be 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -4265,7 +4265,7 @@ case "${target}" in ;; 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) @@ -4418,6 +4418,21 @@ case "${target}" in 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*-*-*) @@ -4937,7 +4952,7 @@ case ${target} in 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 --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 55b440785..717f3d032 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -14127,7 +14127,7 @@ mips_process_sync_loop (rtx_insn *insn, rtx *operands) 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) { @@ -14148,6 +14148,10 @@ mips_process_sync_loop (rtx_insn *insn, rtx *operands) /* 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); @@ -14257,13 +14261,18 @@ mips_process_sync_loop (rtx_insn *insn, rtx *operands) 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 --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index d2205f089..9605b4bb7 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -655,6 +655,8 @@ struct mips_cpu_info { builtin_define ("__mips_no_lxc1_sxc1"); \ if (!ISA_HAS_UNFUSED_MADD4 && !ISA_HAS_FUSED_MADD4) \ builtin_define ("__mips_no_madd4"); \ + if (FIX_LOONGSON3_LLSC) \ + builtin_define ("__mips_fix_loongson3_llsc"); \ } \ while (0) @@ -890,7 +892,9 @@ struct mips_cpu_info { {"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, @@ -1415,6 +1419,7 @@ struct mips_cpu_info { %{mfix-rm7000} %{mno-fix-rm7000} \ %{mfix-vr4120} %{mfix-vr4130} \ %{mfix-24k} \ +%{mfix-loongson3-llsc} %{mno-fix-loongson3-llsc} \ %{noasmopt:-O0; O0|fno-delayed-branch:-O1; O*:-O2; :-O1} \ %(subtarget_asm_debugging_spec) \ %{mabi=*} %{!mabi=*: %(asm_abi_default_spec)} \ diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt index 753321004..6a7567a4e 100644 --- a/gcc/config/mips/mips.opt +++ b/gcc/config/mips/mips.opt @@ -193,6 +193,10 @@ mfix4300 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 --git a/gcc/testsuite/gcc.target/mips/fix-loongson3-llsc.c b/gcc/testsuite/gcc.target/mips/fix-loongson3-llsc.c new file mode 100644 index 000000000..f82e39a47 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fix-loongson3-llsc.c @@ -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 --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp index 002cc280e..975c51f82 100644 --- a/gcc/testsuite/gcc.target/mips/mips.exp +++ b/gcc/testsuite/gcc.target/mips/mips.exp @@ -281,6 +281,7 @@ foreach option { fix-r4000 fix-r10000 fix-vr4130 + fix-loongson3-llsc gpopt local-sdata long-calls