[clang] 135a927 - [Clang][LoongArch] Handle -march/-m{single,double,soft}-float/-mfpu options
via cfe-commits
cfe-commits at lists.llvm.org
Thu Nov 10 01:30:57 PST 2022
Author: Weining Lu
Date: 2022-11-10T17:27:28+08:00
New Revision: 135a9272a4c99b7f960086d0bf9d7e7da4c0396d
URL: https://github.com/llvm/llvm-project/commit/135a9272a4c99b7f960086d0bf9d7e7da4c0396d
DIFF: https://github.com/llvm/llvm-project/commit/135a9272a4c99b7f960086d0bf9d7e7da4c0396d.diff
LOG: [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
Added:
clang/test/Driver/loongarch-march-error.c
clang/test/Driver/loongarch-march.c
clang/test/Driver/loongarch-mdouble-float.c
clang/test/Driver/loongarch-mfpu-error.c
clang/test/Driver/loongarch-mfpu.c
clang/test/Driver/loongarch-msingle-float.c
clang/test/Driver/loongarch-msoft-float.c
llvm/include/llvm/Support/LoongArchTargetParser.def
llvm/include/llvm/Support/LoongArchTargetParser.h
llvm/lib/Support/LoongArchTargetParser.cpp
Modified:
clang/include/clang/Basic/DiagnosticDriverKinds.td
clang/include/clang/Driver/Options.td
clang/lib/Driver/ToolChains/Arch/LoongArch.cpp
clang/lib/Driver/ToolChains/Arch/LoongArch.h
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Driver/ToolChains/Linux.cpp
clang/test/Driver/loongarch-default-features.c
llvm/lib/Support/CMakeLists.txt
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 12c246b32cfd4..1b24d9c70a0b6 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 c096c58440045..debe038196c06 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 d364a2e8f7a8e..576677a5f38e1 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 eb09419c2c1ba..2f85dd0e0e88f 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 8edef656be09d..06336189d8706 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 b6a93fe95e276..6fc3d7793ec63 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 833ee4fd3fafa..27cca85abb6a4 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 0000000000000..ec1e065f1d06c
--- /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 0000000000000..486feb0797ac5
--- /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 0000000000000..fb8b13bf8ab25
--- /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 0000000000000..6c1fc165c7361
--- /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 0000000000000..d5fb293d917b4
--- /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 0000000000000..6084b80f74c88
--- /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 0000000000000..09e49f9873c3f
--- /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;
+}
diff --git a/llvm/include/llvm/Support/LoongArchTargetParser.def b/llvm/include/llvm/Support/LoongArchTargetParser.def
new file mode 100644
index 0000000000000..4ebdcc012bdb8
--- /dev/null
+++ b/llvm/include/llvm/Support/LoongArchTargetParser.def
@@ -0,0 +1,25 @@
+#ifndef LOONGARCH_FEATURE
+#define LOONGARCH_FEATURE(NAME, KIND)
+#endif
+
+LOONGARCH_FEATURE("invalid", FK_INVALID)
+LOONGARCH_FEATURE("none", FK_NONE)
+LOONGARCH_FEATURE("+64bit", FK_64BIT)
+LOONGARCH_FEATURE("+f", FK_FP32)
+LOONGARCH_FEATURE("+d", FK_FP64)
+LOONGARCH_FEATURE("+lsx", FK_LSX)
+LOONGARCH_FEATURE("+lasx", FK_LASX)
+LOONGARCH_FEATURE("+lbt", FK_LBT)
+LOONGARCH_FEATURE("+lvz", FK_LVZ)
+
+#undef LOONGARCH_FEATURE
+
+#ifndef LOONGARCH_ARCH
+#define LOONGARCH_ARCH(NAME, KIND, FEATURES)
+#endif
+
+LOONGARCH_ARCH("invalid", AK_INVALID, FK_INVALID)
+LOONGARCH_ARCH("loongarch64", AK_LOONGARCH64, FK_64BIT | FK_FP32 | FK_FP64)
+LOONGARCH_ARCH("la464", AK_LA464, FK_64BIT | FK_FP32 | FK_FP64 | FK_LSX | FK_LASX)
+
+#undef LOONGARCH_ARCH
diff --git a/llvm/include/llvm/Support/LoongArchTargetParser.h b/llvm/include/llvm/Support/LoongArchTargetParser.h
new file mode 100644
index 0000000000000..acf8117686404
--- /dev/null
+++ b/llvm/include/llvm/Support/LoongArchTargetParser.h
@@ -0,0 +1,74 @@
+//==-- LoongArch64TargetParser - Parser for LoongArch64 features --*- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a target parser to recognise LoongArch hardware features
+// such as CPU/ARCH and extension names.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_LOONGARCHTARGETPARSER_H
+#define LLVM_SUPPORT_LOONGARCHTARGETPARSER_H
+
+#include "llvm/ADT/Triple.h"
+#include <vector>
+
+namespace llvm {
+class StringRef;
+
+namespace LoongArch {
+
+enum FeatureKind : uint32_t {
+ FK_INVALID = 0,
+ FK_NONE = 1,
+
+ // 64-bit ISA is available.
+ FK_64BIT = 1 << 1,
+
+ // Single-precision floating-point instructions are available.
+ FK_FP32 = 1 << 2,
+
+ // Double-precision floating-point instructions are available.
+ FK_FP64 = 1 << 3,
+
+ // Loongson SIMD Extension is available.
+ FK_LSX = 1 << 4,
+
+ // Loongson Advanced SIMD Extension is available.
+ FK_LASX = 1 << 5,
+
+ // Loongson Binary Translation Extension is available.
+ FK_LBT = 1 << 6,
+
+ // Loongson Virtualization Extension is available.
+ FK_LVZ = 1 << 7,
+};
+
+struct FeatureInfo {
+ StringRef Name;
+ FeatureKind Kind;
+};
+
+enum class ArchKind {
+#define LOONGARCH_ARCH(NAME, KIND, FEATURES) KIND,
+#include "LoongArchTargetParser.def"
+};
+
+struct ArchInfo {
+ StringRef Name;
+ ArchKind Kind;
+ uint32_t Features;
+};
+
+ArchKind parseArch(StringRef Arch);
+bool getArchFeatures(StringRef Arch, std::vector<StringRef> &Features);
+
+} // namespace LoongArch
+
+} // namespace llvm
+
+#endif // LLVM_SUPPORT_LOONGARCHTARGETPARSER_H
diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt
index 023d50793effa..e6ad29e0022b6 100644
--- a/llvm/lib/Support/CMakeLists.txt
+++ b/llvm/lib/Support/CMakeLists.txt
@@ -187,6 +187,7 @@ add_llvm_component_library(LLVMSupport
LineIterator.cpp
Locale.cpp
LockFileManager.cpp
+ LoongArchTargetParser.cpp
LowLevelType.cpp
ManagedStatic.cpp
MathExtras.cpp
diff --git a/llvm/lib/Support/LoongArchTargetParser.cpp b/llvm/lib/Support/LoongArchTargetParser.cpp
new file mode 100644
index 0000000000000..dbc8184a2f496
--- /dev/null
+++ b/llvm/lib/Support/LoongArchTargetParser.cpp
@@ -0,0 +1,53 @@
+//==-- LoongArch64TargetParser - Parser for LoongArch64 features --*- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a target parser to recognise LoongArch hardware features
+// such as CPU/ARCH and extension names.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/LoongArchTargetParser.h"
+#include "llvm/ADT/StringSwitch.h"
+
+using namespace llvm;
+using namespace llvm::LoongArch;
+
+const FeatureInfo AllFeatures[] = {
+#define LOONGARCH_FEATURE(NAME, KIND) {NAME, KIND},
+#include "llvm/Support/LoongArchTargetParser.def"
+};
+
+const ArchInfo AllArchs[] = {
+#define LOONGARCH_ARCH(NAME, KIND, FEATURES) \
+ {NAME, LoongArch::ArchKind::KIND, FEATURES},
+#include "llvm/Support/LoongArchTargetParser.def"
+};
+
+LoongArch::ArchKind LoongArch::parseArch(StringRef Arch) {
+ for (const auto A : AllArchs) {
+ if (A.Name == Arch)
+ return A.Kind;
+ }
+
+ return LoongArch::ArchKind::AK_INVALID;
+}
+
+bool LoongArch::getArchFeatures(StringRef Arch,
+ std::vector<StringRef> &Features) {
+ for (const auto A : AllArchs) {
+ if (A.Name == Arch) {
+ for (const auto F : AllFeatures) {
+ if ((A.Features & F.Kind) == F.Kind && F.Kind != FK_INVALID) {
+ Features.push_back(F.Name);
+ }
+ }
+ return true;
+ }
+ }
+ return false;
+}
More information about the cfe-commits
mailing list