Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
authorWeining Lu <luweining@loongson.cn>2022-10-27 15:28:56 +0300
committergonglingqin <gonglingqin@loongson.cn>2022-11-10 12:27:28 +0300
commit135a9272a4c99b7f960086d0bf9d7e7da4c0396d (patch)
tree5ccb8b8fbe2ce167358a0ae25d7f7c89f32621e7 /clang
parent098e20134af5d32a73bd124ca3ce001baa569cab (diff)
[Clang][LoongArch] Handle -march/-m{single,double,soft}-float/-mfpu options
This patch adds options -march, -msingle-float, -mdouble-float, -msoft-float and -mfpu for LoongArch. Clang options `msingle_float` and `mdouble_float` are moved from `m_mips_Features_Group` to `m_Group` because now more than targets use them. Reference: https://github.com/loongson/LoongArch-Documentation/blob/main/docs/LoongArch-toolchain-conventions-EN.adoc TODO: add -mtune. Differential Revision: https://reviews.llvm.org/D136146
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/DiagnosticDriverKinds.td3
-rw-r--r--clang/include/clang/Driver/Options.td4
-rw-r--r--clang/lib/Driver/ToolChains/Arch/LoongArch.cpp92
-rw-r--r--clang/lib/Driver/ToolChains/Arch/LoongArch.h5
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp5
-rw-r--r--clang/lib/Driver/ToolChains/Linux.cpp14
-rw-r--r--clang/test/Driver/loongarch-default-features.c4
-rw-r--r--clang/test/Driver/loongarch-march-error.c7
-rw-r--r--clang/test/Driver/loongarch-march.c32
-rw-r--r--clang/test/Driver/loongarch-mdouble-float.c18
-rw-r--r--clang/test/Driver/loongarch-mfpu-error.c4
-rw-r--r--clang/test/Driver/loongarch-mfpu.c47
-rw-r--r--clang/test/Driver/loongarch-msingle-float.c18
-rw-r--r--clang/test/Driver/loongarch-msoft-float.c18
14 files changed, 250 insertions, 21 deletions
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 12c246b32cfd..1b24d9c70a0b 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -691,4 +691,7 @@ def warn_drv_sarif_format_unstable : Warning<
def err_drv_riscv_unsupported_with_linker_relaxation : Error<
"%0 is unsupported with RISC-V linker relaxation (-mrelax)">;
+
+def err_drv_loongarch_invalid_mfpu_EQ : Error<
+ "invalid argument '%0' to -mfpu=; must be one of: 64, 32, 0, none">;
}
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index c096c5844004..debe038196c0 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3910,8 +3910,8 @@ def mdsp : Flag<["-"], "mdsp">, Group<m_mips_Features_Group>;
def mno_dsp : Flag<["-"], "mno-dsp">, Group<m_mips_Features_Group>;
def mdspr2 : Flag<["-"], "mdspr2">, Group<m_mips_Features_Group>;
def mno_dspr2 : Flag<["-"], "mno-dspr2">, Group<m_mips_Features_Group>;
-def msingle_float : Flag<["-"], "msingle-float">, Group<m_mips_Features_Group>;
-def mdouble_float : Flag<["-"], "mdouble-float">, Group<m_mips_Features_Group>;
+def msingle_float : Flag<["-"], "msingle-float">, Group<m_Group>;
+def mdouble_float : Flag<["-"], "mdouble-float">, Group<m_Group>;
def mmadd4 : Flag<["-"], "mmadd4">, Group<m_mips_Features_Group>,
HelpText<"Enable the generation of 4-operand madd.s, madd.d and related instructions.">;
def mno_madd4 : Flag<["-"], "mno-madd4">, Group<m_mips_Features_Group>,
diff --git a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp
index d364a2e8f7a8..576677a5f38e 100644
--- a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp
@@ -7,33 +7,109 @@
//===----------------------------------------------------------------------===//
#include "LoongArch.h"
+#include "clang/Basic/DiagnosticDriver.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Support/LoongArchTargetParser.h"
+using namespace clang::driver;
using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
-StringRef loongarch::getLoongArchABI(const ArgList &Args,
+StringRef loongarch::getLoongArchABI(const Driver &D, const ArgList &Args,
const llvm::Triple &Triple) {
assert((Triple.getArch() == llvm::Triple::loongarch32 ||
Triple.getArch() == llvm::Triple::loongarch64) &&
"Unexpected triple");
+ bool IsLA32 = Triple.getArch() == llvm::Triple::loongarch32;
+
+ // Check -m*-float firstly since they have highest priority.
+ if (const Arg *A = Args.getLastArg(options::OPT_mdouble_float,
+ options::OPT_msingle_float,
+ options::OPT_msoft_float)) {
+ if (A->getOption().matches(options::OPT_mdouble_float))
+ return IsLA32 ? "ilp32d" : "lp64d";
+ if (A->getOption().matches(options::OPT_msingle_float))
+ return IsLA32 ? "ilp32f" : "lp64f";
+ if (A->getOption().matches(options::OPT_msoft_float))
+ return IsLA32 ? "ilp32s" : "lp64s";
+ }
// If `-mabi=` is specified, use it.
if (const Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
return A->getValue();
+ // Select abi based on -mfpu=xx.
+ if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) {
+ StringRef FPU = A->getValue();
+ if (FPU == "64")
+ return IsLA32 ? "ilp32d" : "lp64d";
+ if (FPU == "32")
+ return IsLA32 ? "ilp32f" : "lp64f";
+ if (FPU == "0" || FPU == "none")
+ return IsLA32 ? "ilp32s" : "lp64s";
+ D.Diag(diag::err_drv_loongarch_invalid_mfpu_EQ) << FPU;
+ }
+
// Choose a default based on the triple.
- // TODO: select appropiate ABI.
- return Triple.getArch() == llvm::Triple::loongarch32 ? "ilp32d" : "lp64d";
+ return IsLA32 ? "ilp32d" : "lp64d";
}
void loongarch::getLoongArchTargetFeatures(const Driver &D,
const llvm::Triple &Triple,
const ArgList &Args,
std::vector<StringRef> &Features) {
- // FIXME: hornor various clang options that may affect target features, e.g.
- // -march/-mtune/-mdouble-float/-msingle-float/-msoft-float/-mfpu. See:
- // https://loongson.github.io/LoongArch-Documentation/LoongArch-toolchain-conventions-EN.html
- Features.push_back("+f");
- Features.push_back("+d");
+ StringRef ArchName;
+ llvm::LoongArch::ArchKind ArchKind = llvm::LoongArch::ArchKind::AK_INVALID;
+ if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
+ ArchKind = llvm::LoongArch::parseArch(A->getValue());
+ if (ArchKind == llvm::LoongArch::ArchKind::AK_INVALID) {
+ D.Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
+ return;
+ }
+ ArchName = A->getValue();
+ }
+
+ // TODO: handle -march=native and -mtune=xx.
+
+ // Select a default arch name.
+ if (ArchName.empty() && Triple.getArch() == llvm::Triple::loongarch64)
+ ArchName = "loongarch64";
+
+ if (!ArchName.empty())
+ llvm::LoongArch::getArchFeatures(ArchName, Features);
+
+ // Select floating-point features determined by -mdouble-float,
+ // -msingle-float, -msoft-float and -mfpu.
+ // Note: -m*-float wins any other options.
+ if (const Arg *A = Args.getLastArg(options::OPT_mdouble_float,
+ options::OPT_msingle_float,
+ options::OPT_msoft_float)) {
+ if (A->getOption().matches(options::OPT_mdouble_float)) {
+ Features.push_back("+f");
+ Features.push_back("+d");
+ } else if (A->getOption().matches(options::OPT_msingle_float)) {
+ Features.push_back("+f");
+ Features.push_back("-d");
+ } else /*Soft-float*/ {
+ Features.push_back("-f");
+ Features.push_back("-d");
+ }
+ } else if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) {
+ StringRef FPU = A->getValue();
+ if (FPU == "64") {
+ Features.push_back("+f");
+ Features.push_back("+d");
+ } else if (FPU == "32") {
+ Features.push_back("+f");
+ Features.push_back("-d");
+ } else if (FPU == "0" || FPU == "none") {
+ Features.push_back("-f");
+ Features.push_back("-d");
+ } else {
+ D.Diag(diag::err_drv_loongarch_invalid_mfpu_EQ) << FPU;
+ }
+ }
}
diff --git a/clang/lib/Driver/ToolChains/Arch/LoongArch.h b/clang/lib/Driver/ToolChains/Arch/LoongArch.h
index eb09419c2c1b..2f85dd0e0e88 100644
--- a/clang/lib/Driver/ToolChains/Arch/LoongArch.h
+++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.h
@@ -17,7 +17,10 @@ namespace clang {
namespace driver {
namespace tools {
namespace loongarch {
-StringRef getLoongArchABI(const llvm::opt::ArgList &Args,
+void getLoongArchTargetFeatures(const Driver &D, const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args,
+ std::vector<llvm::StringRef> &Features);
+StringRef getLoongArchABI(const Driver &D, const llvm::opt::ArgList &Args,
const llvm::Triple &Triple);
void getLoongArchTargetFeatures(const Driver &D, const llvm::Triple &Triple,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 8edef656be09..06336189d870 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1921,8 +1921,9 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
void Clang::AddLoongArchTargetArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
CmdArgs.push_back("-target-abi");
- CmdArgs.push_back(
- loongarch::getLoongArchABI(Args, getToolChain().getTriple()).data());
+ CmdArgs.push_back(loongarch::getLoongArchABI(getToolChain().getDriver(), Args,
+ getToolChain().getTriple())
+ .data());
}
void Clang::AddMIPSTargetArgs(const ArgList &Args,
diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
index b6a93fe95e27..6fc3d7793ec6 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -469,16 +469,18 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const {
}
case llvm::Triple::loongarch32: {
LibDir = "lib32";
- Loader = ("ld-linux-loongarch-" +
- tools::loongarch::getLoongArchABI(Args, Triple) + ".so.1")
- .str();
+ Loader =
+ ("ld-linux-loongarch-" +
+ tools::loongarch::getLoongArchABI(getDriver(), Args, Triple) + ".so.1")
+ .str();
break;
}
case llvm::Triple::loongarch64: {
LibDir = "lib64";
- Loader = ("ld-linux-loongarch-" +
- tools::loongarch::getLoongArchABI(Args, Triple) + ".so.1")
- .str();
+ Loader =
+ ("ld-linux-loongarch-" +
+ tools::loongarch::getLoongArchABI(getDriver(), Args, Triple) + ".so.1")
+ .str();
break;
}
case llvm::Triple::m68k:
diff --git a/clang/test/Driver/loongarch-default-features.c b/clang/test/Driver/loongarch-default-features.c
index 833ee4fd3faf..27cca85abb6a 100644
--- a/clang/test/Driver/loongarch-default-features.c
+++ b/clang/test/Driver/loongarch-default-features.c
@@ -1,8 +1,8 @@
// RUN: %clang --target=loongarch32 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA32
// RUN: %clang --target=loongarch64 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA64
-// LA32: "target-features"="+d,+f"
-// LA64: "target-features"="+d,+f"
+// LA32-NOT: "target-features"=
+// LA64: "target-features"="+64bit,+d,+f"
/// Dummy function
int foo(void) {
diff --git a/clang/test/Driver/loongarch-march-error.c b/clang/test/Driver/loongarch-march-error.c
new file mode 100644
index 000000000000..ec1e065f1d06
--- /dev/null
+++ b/clang/test/Driver/loongarch-march-error.c
@@ -0,0 +1,7 @@
+// RUN: not %clang --target=loongarch64 -march=loongarch -fsyntax-only %s 2>&1 \
+// RUN: | FileCheck --check-prefix=LOONGARCH %s
+// LOONGARCH: error: invalid arch name '-march=loongarch'
+
+// RUN: not %clang --target=loongarch64 -march=LA464 -fsyntax-only %s 2>&1 \
+// RUN: | FileCheck --check-prefix=LA464-UPPER %s
+// LA464-UPPER: error: invalid arch name '-march=LA464'
diff --git a/clang/test/Driver/loongarch-march.c b/clang/test/Driver/loongarch-march.c
new file mode 100644
index 000000000000..486feb0797ac
--- /dev/null
+++ b/clang/test/Driver/loongarch-march.c
@@ -0,0 +1,32 @@
+// RUN: %clang --target=loongarch64 -march=loongarch64 -fsyntax-only %s -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CC1-LOONGARCH64
+// RUN: %clang --target=loongarch64 -march=la464 -fsyntax-only %s -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CC1-LA464
+// RUN: %clang --target=loongarch64 -march=loongarch64 -S -emit-llvm %s -o - \
+// RUN: | FileCheck %s --check-prefix=IR-LOONGARCH64
+// RUN: %clang --target=loongarch64 -march=la464 -S -emit-llvm %s -o - \
+// RUN: | FileCheck %s --check-prefix=IR-LA464
+
+// CC1-LOONGARCH64-NOT: "-target-feature"
+// CC1-LOONGARCH64: "-target-feature" "+64bit"
+// CC1-LOONGARCH64-SAME: {{^}} "-target-feature" "+f"
+// CC1-LOONGARCH64-SAME: {{^}} "-target-feature" "+d"
+// CC1-LOONGARCH64-NOT: "-target-feature"
+// CC1-LOONGARCH64: "-target-abi" "lp64d"
+
+// CC1-LA464-NOT: "-target-feature"
+// CC1-LA464: "-target-feature" "+64bit"
+// CC1-LA464-SAME: {{^}} "-target-feature" "+f"
+// CC1-LA464-SAME: {{^}} "-target-feature" "+d"
+// CC1-LA464-SAME: {{^}} "-target-feature" "+lsx"
+// CC1-LA464-SAME: {{^}} "-target-feature" "+lasx"
+// CC1-LA464-NOT: "-target-feature"
+// CC1-LA464: "-target-abi" "lp64d"
+
+// IR-LOONGARCH64: attributes #{{[0-9]+}} ={{.*}}"target-features"="+64bit,+d,+f"
+// IR-LA464: attributes #{{[0-9]+}} ={{.*}}"target-features"="+64bit,+d,+f,+lasx,+lsx"
+
+/// Dummy function
+int foo(void) {
+ return 3;
+}
diff --git a/clang/test/Driver/loongarch-mdouble-float.c b/clang/test/Driver/loongarch-mdouble-float.c
new file mode 100644
index 000000000000..fb8b13bf8ab2
--- /dev/null
+++ b/clang/test/Driver/loongarch-mdouble-float.c
@@ -0,0 +1,18 @@
+// RUN: %clang --target=loongarch64 -mdouble-float -fsyntax-only %s -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CC1
+// RUN: %clang --target=loongarch64 -mdouble-float -S -emit-llvm %s -o - \
+// RUN: | FileCheck %s --check-prefix=IR
+
+// CC1-NOT: "-target-feature"
+// CC1: "-target-feature" "+64bit"
+// CC1-SAME: {{^}} "-target-feature" "+f"
+// CC1-SAME: {{^}} "-target-feature" "+d"
+// CC1-NOT: "-target-feature"
+// CC1: "-target-abi" "lp64d"
+
+// IR: attributes #{{[0-9]+}} ={{.*}}"target-features"="+64bit,+d,+f"
+
+/// Dummy function
+int foo(void) {
+ return 3;
+}
diff --git a/clang/test/Driver/loongarch-mfpu-error.c b/clang/test/Driver/loongarch-mfpu-error.c
new file mode 100644
index 000000000000..6c1fc165c736
--- /dev/null
+++ b/clang/test/Driver/loongarch-mfpu-error.c
@@ -0,0 +1,4 @@
+// RUN: %clang --target=loongarch64 -mfpu=xxx -fsyntax-only %s -### 2>&1 \
+// RUN: | FileCheck %s
+
+// CHECK: invalid argument 'xxx' to -mfpu=; must be one of: 64, 32, 0, none
diff --git a/clang/test/Driver/loongarch-mfpu.c b/clang/test/Driver/loongarch-mfpu.c
new file mode 100644
index 000000000000..d5fb293d917b
--- /dev/null
+++ b/clang/test/Driver/loongarch-mfpu.c
@@ -0,0 +1,47 @@
+// RUN: %clang --target=loongarch64 -mfpu=64 -fsyntax-only %s -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CC1-FPU64
+// RUN: %clang --target=loongarch64 -mfpu=32 -fsyntax-only %s -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CC1-FPU32
+// RUN: %clang --target=loongarch64 -mfpu=0 -fsyntax-only %s -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CC1-FPU0
+// RUN: %clang --target=loongarch64 -mfpu=none -fsyntax-only %s -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CC1-FPU0
+
+// RUN: %clang --target=loongarch64 -mfpu=64 -S -emit-llvm %s -o - \
+// RUN: | FileCheck %s --check-prefix=IR-FPU64
+// RUN: %clang --target=loongarch64 -mfpu=32 -S -emit-llvm %s -o - \
+// RUN: | FileCheck %s --check-prefix=IR-FPU32
+// RUN: %clang --target=loongarch64 -mfpu=0 -S -emit-llvm %s -o - \
+// RUN: | FileCheck %s --check-prefix=IR-FPU0
+// RUN: %clang --target=loongarch64 -mfpu=none -S -emit-llvm %s -o - \
+// RUN: | FileCheck %s --check-prefix=IR-FPU0
+
+// CC1-FPU64-NOT: "-target-feature"
+// CC1-FPU64: "-target-feature" "+64bit"
+// CC1-FPU64-SAME: "-target-feature" "+f"
+// CC1-FPU64-SAME: "-target-feature" "+d"
+// CC1-FPU64-NOT: "-target-feature"
+// CC1-FPU64: "-target-abi" "lp64d"
+
+// CC1-FPU32-NOT: "-target-feature"
+// CC1-FPU32: "-target-feature" "+64bit"
+// CC1-FPU32-SAME: "-target-feature" "+f"
+// CC1-FPU32-SAME: "-target-feature" "-d"
+// CC1-FPU32-NOT: "-target-feature"
+// CC1-FPU32: "-target-abi" "lp64f"
+
+// CC1-FPU0-NOT: "-target-feature"
+// CC1-FPU0: "-target-feature" "+64bit"
+// CC1-FPU0-SAME: "-target-feature" "-f"
+// CC1-FPU0-SAME: "-target-feature" "-d"
+// CC1-FPU0-NOT: "-target-feature"
+// CC1-FPU0: "-target-abi" "lp64s"
+
+// IR-FPU64: attributes #{{[0-9]+}} ={{.*}}"target-features"="+64bit,+d,+f"
+// IR-FPU32: attributes #{{[0-9]+}} ={{.*}}"target-features"="+64bit,+f,-d"
+// IR-FPU0: attributes #{{[0-9]+}} ={{.*}}"target-features"="+64bit,-d,-f"
+
+/// Dummy function
+int foo(void) {
+ return 3;
+}
diff --git a/clang/test/Driver/loongarch-msingle-float.c b/clang/test/Driver/loongarch-msingle-float.c
new file mode 100644
index 000000000000..6084b80f74c8
--- /dev/null
+++ b/clang/test/Driver/loongarch-msingle-float.c
@@ -0,0 +1,18 @@
+// RUN: %clang --target=loongarch64 -msingle-float -fsyntax-only %s -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CC1
+// RUN: %clang --target=loongarch64 -msingle-float -S -emit-llvm %s -o - \
+// RUN: | FileCheck %s --check-prefix=IR
+
+// CC1-NOT: "-target-feature"
+// CC1: "-target-feature" "+64bit"
+// CC1-SAME: {{^}} "-target-feature" "+f"
+// CC1-SAME: {{^}} "-target-feature" "-d"
+// CC1-NOT: "-target-feature"
+// CC1: "-target-abi" "lp64f"
+
+// IR: attributes #{{[0-9]+}} ={{.*}}"target-features"="+64bit,+f,-d"
+
+/// Dummy function
+int foo(void) {
+ return 3;
+}
diff --git a/clang/test/Driver/loongarch-msoft-float.c b/clang/test/Driver/loongarch-msoft-float.c
new file mode 100644
index 000000000000..09e49f9873c3
--- /dev/null
+++ b/clang/test/Driver/loongarch-msoft-float.c
@@ -0,0 +1,18 @@
+// RUN: %clang --target=loongarch64 -msoft-float -fsyntax-only %s -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CC1
+// RUN: %clang --target=loongarch64 -msoft-float -S -emit-llvm %s -o - \
+// RUN: | FileCheck %s --check-prefix=IR
+
+// CC1-NOT: "-target-feature"
+// CC1: "-target-feature" "+64bit"
+// CC1-SAME: {{^}} "-target-feature" "-f"
+// CC1-SAME: {{^}} "-target-feature" "-d"
+// CC1-NOT: "-target-feature"
+// CC1: "-target-abi" "lp64s"
+
+// IR: attributes #{{[0-9]+}} ={{.*}}"target-features"="+64bit,-d,-f"
+
+/// Dummy function
+int foo(void) {
+ return 3;
+}