[llvm] 294d1ea - [RISCV] Add support for -mcpu option.
Zakk Chen via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 16 11:46:51 PDT 2020
Author: Zakk Chen
Date: 2020-07-16T11:46:22-07:00
New Revision: 294d1eae75bf8867821a4491f0d67445227f8470
URL: https://github.com/llvm/llvm-project/commit/294d1eae75bf8867821a4491f0d67445227f8470
DIFF: https://github.com/llvm/llvm-project/commit/294d1eae75bf8867821a4491f0d67445227f8470.diff
LOG: [RISCV] Add support for -mcpu option.
Summary:
1. gcc uses `-march` and `-mtune` flag to chose arch and
pipeline model, but clang does not have `-mtune` flag,
we uses `-mcpu` to chose both infos.
2. Add SiFive e31 and u54 cpu which have default march
and pipeline model.
3. Specific `-mcpu` with rocket-rv[32|64] would select
pipeline model only, and use the driver's arch choosing
logic to get default arch.
Reviewers: lenary, asb, evandro, HsiangKai
Reviewed By: lenary, asb, evandro
Tags: #llvm, #clang
Differential Revision: https://reviews.llvm.org/D71124
Added:
clang/test/Driver/riscv-cpus.c
llvm/include/llvm/Support/RISCVTargetParser.def
Modified:
clang/lib/Basic/Targets/RISCV.cpp
clang/lib/Basic/Targets/RISCV.h
clang/lib/Driver/ToolChains/Arch/RISCV.cpp
clang/lib/Driver/ToolChains/CommonArgs.cpp
clang/test/Driver/riscv-arch.c
clang/test/Misc/target-invalid-cpu-note.c
llvm/include/llvm/Support/TargetParser.h
llvm/lib/Support/TargetParser.cpp
llvm/lib/Target/RISCV/RISCV.td
Removed:
################################################################################
diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp
index 522776437cd2..4ba703c8dd1a 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -13,6 +13,7 @@
#include "RISCV.h"
#include "clang/Basic/MacroBuilder.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/TargetParser.h"
using namespace clang;
using namespace clang::targets;
@@ -166,3 +167,23 @@ bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
return true;
}
+
+bool RISCV32TargetInfo::isValidCPUName(StringRef Name) const {
+ return llvm::RISCV::checkCPUKind(llvm::RISCV::parseCPUKind(Name),
+ /*Is64Bit=*/false);
+}
+
+void RISCV32TargetInfo::fillValidCPUList(
+ SmallVectorImpl<StringRef> &Values) const {
+ llvm::RISCV::fillValidCPUArchList(Values, false);
+}
+
+bool RISCV64TargetInfo::isValidCPUName(StringRef Name) const {
+ return llvm::RISCV::checkCPUKind(llvm::RISCV::parseCPUKind(Name),
+ /*Is64Bit=*/true);
+}
+
+void RISCV64TargetInfo::fillValidCPUList(
+ SmallVectorImpl<StringRef> &Values) const {
+ llvm::RISCV::fillValidCPUArchList(Values, true);
+}
diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h
index 73652b409e9c..6db526da4c59 100644
--- a/clang/lib/Basic/Targets/RISCV.h
+++ b/clang/lib/Basic/Targets/RISCV.h
@@ -24,7 +24,7 @@ namespace targets {
// RISC-V Target
class RISCVTargetInfo : public TargetInfo {
protected:
- std::string ABI;
+ std::string ABI, CPU;
bool HasM;
bool HasA;
bool HasF;
@@ -44,6 +44,13 @@ class RISCVTargetInfo : public TargetInfo {
WIntType = UnsignedInt;
}
+ bool setCPU(const std::string &Name) override {
+ if (!isValidCPUName(Name))
+ return false;
+ CPU = Name;
+ return true;
+ }
+
StringRef getABI() const override { return ABI; }
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
@@ -97,6 +104,9 @@ class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
return false;
}
+ bool isValidCPUName(StringRef Name) const override;
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
+
void setMaxAtomicWidth() override {
MaxAtomicPromoteWidth = 128;
@@ -121,6 +131,9 @@ class LLVM_LIBRARY_VISIBILITY RISCV64TargetInfo : public RISCVTargetInfo {
return false;
}
+ bool isValidCPUName(StringRef Name) const override;
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
+
void setMaxAtomicWidth() override {
MaxAtomicPromoteWidth = 128;
diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index 80d12e5aa8da..be3f0a07b576 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -446,6 +446,19 @@ static bool getArchFeatures(const Driver &D, StringRef MArch,
return true;
}
+// Get features except standard extension feature
+void getRISCFeaturesFromMcpu(const Driver &D, const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args,
+ const llvm::opt::Arg *A, StringRef Mcpu,
+ std::vector<StringRef> &Features) {
+ bool Is64Bit = (Triple.getArch() == llvm::Triple::riscv64);
+ llvm::RISCV::CPUKind CPUKind = llvm::RISCV::parseCPUKind(Mcpu);
+ if (!llvm::RISCV::checkCPUKind(CPUKind, Is64Bit) ||
+ !llvm::RISCV::getCPUFeaturesExceptStdExt(CPUKind, Features)) {
+ D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
+ }
+}
+
void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args,
std::vector<StringRef> &Features) {
@@ -454,6 +467,11 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
if (!getArchFeatures(D, MArch, Features, Args))
return;
+ // If users give march and mcpu, get std extension feature from MArch
+ // and other features (ex. mirco architecture feature) from mcpu
+ if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
+ getRISCFeaturesFromMcpu(D, Triple, Args, A, A->getValue(), Features);
+
// Handle features corresponding to "-ffixed-X" options
if (Args.hasArg(options::OPT_ffixed_x1))
Features.push_back("+reserve-x1");
@@ -543,11 +561,9 @@ StringRef riscv::getRISCVABI(const ArgList &Args, const llvm::Triple &Triple) {
// GCC's logic around choosing a default `-mabi=` is complex. If GCC is not
// configured using `--with-abi=`, then the logic for the default choice is
- // defined in config.gcc. This function is based on the logic in GCC 9.2.0. We
- // deviate from GCC's default only on baremetal targets (UnknownOS) where
- // neither `-march` nor `-mabi` is specified.
+ // defined in config.gcc. This function is based on the logic in GCC 9.2.0.
//
- // The logic uses the following, in order:
+ // The logic used in GCC 9.2.0 is the following, in order:
// 1. Explicit choices using `--with-abi=`
// 2. A default based on `--with-arch=`, if provided
// 3. A default based on the target triple's arch
@@ -556,38 +572,40 @@ StringRef riscv::getRISCVABI(const ArgList &Args, const llvm::Triple &Triple) {
//
// Clang does not have `--with-arch=` or `--with-abi=`, so we use `-march=`
// and `-mabi=` respectively instead.
+ //
+ // In order to make chosing logic more clear, Clang uses the following logic,
+ // in order:
+ // 1. Explicit choices using `-mabi=`
+ // 2. A default based on the architecture as determined by getRISCVArch
+ // 3. Choose a default based on the triple
// 1. If `-mabi=` is specified, use it.
if (const Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
return A->getValue();
- // 2. Choose a default based on `-march=`
+ // 2. Choose a default based on the target architecture.
//
// rv32g | rv32*d -> ilp32d
// rv32e -> ilp32e
// rv32* -> ilp32
// rv64g | rv64*d -> lp64d
// rv64* -> lp64
- if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
- StringRef MArch = A->getValue();
-
- if (MArch.startswith_lower("rv32")) {
- // FIXME: parse `March` to find `D` extension properly
- if (MArch.substr(4).contains_lower("d") ||
- MArch.startswith_lower("rv32g"))
- return "ilp32d";
- else if (MArch.startswith_lower("rv32e"))
- return "ilp32e";
- else
- return "ilp32";
- } else if (MArch.startswith_lower("rv64")) {
- // FIXME: parse `March` to find `D` extension properly
- if (MArch.substr(4).contains_lower("d") ||
- MArch.startswith_lower("rv64g"))
- return "lp64d";
- else
- return "lp64";
- }
+ StringRef MArch = getRISCVArch(Args, Triple);
+
+ if (MArch.startswith_lower("rv32")) {
+ // FIXME: parse `March` to find `D` extension properly
+ if (MArch.substr(4).contains_lower("d") || MArch.startswith_lower("rv32g"))
+ return "ilp32d";
+ else if (MArch.startswith_lower("rv32e"))
+ return "ilp32e";
+ else
+ return "ilp32";
+ } else if (MArch.startswith_lower("rv64")) {
+ // FIXME: parse `March` to find `D` extension properly
+ if (MArch.substr(4).contains_lower("d") || MArch.startswith_lower("rv64g"))
+ return "lp64d";
+ else
+ return "lp64";
}
// 3. Choose a default based on the triple
@@ -617,10 +635,11 @@ StringRef riscv::getRISCVArch(const llvm::opt::ArgList &Args,
// GCC's logic around choosing a default `-march=` is complex. If GCC is not
// configured using `--with-arch=`, then the logic for the default choice is
// defined in config.gcc. This function is based on the logic in GCC 9.2.0. We
- // deviate from GCC's default only on baremetal targets (UnknownOS) where
- // neither `-march` nor `-mabi` is specified.
+ // deviate from GCC's default on additional `-mcpu` option (GCC does not
+ // support `-mcpu`) and baremetal targets (UnknownOS) where neither `-march`
+ // nor `-mabi` is specified.
//
- // The logic uses the following, in order:
+ // The logic used in GCC 9.2.0 is the following, in order:
// 1. Explicit choices using `--with-arch=`
// 2. A default based on `--with-abi=`, if provided
// 3. A default based on the target triple's arch
@@ -630,6 +649,12 @@ StringRef riscv::getRISCVArch(const llvm::opt::ArgList &Args,
// Clang does not have `--with-arch=` or `--with-abi=`, so we use `-march=`
// and `-mabi=` respectively instead.
//
+ // Clang uses the following logic, in order:
+ // 1. Explicit choices using `-march=`
+ // 2. Based on `-mcpu` if the target CPU has a default ISA string
+ // 3. A default based on `-mabi`, if provided
+ // 4. A default based on the target triple's arch
+ //
// Clang does not yet support MULTILIB_REUSE, so we use `rv{XLEN}imafdc`
// instead of `rv{XLEN}gc` though they are (currently) equivalent.
@@ -637,7 +662,15 @@ StringRef riscv::getRISCVArch(const llvm::opt::ArgList &Args,
if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
return A->getValue();
- // 2. Choose a default based on `-mabi=`
+ // 2. Get march (isa string) based on `-mcpu=`
+ if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
+ StringRef MArch = llvm::RISCV::getMArchFromMcpu(A->getValue());
+ // Bypass if target cpu's default march is empty.
+ if (MArch != "")
+ return MArch;
+ }
+
+ // 3. Choose a default based on `-mabi=`
//
// ilp32e -> rv32e
// ilp32 | ilp32f | ilp32d -> rv32imafdc
@@ -653,7 +686,7 @@ StringRef riscv::getRISCVArch(const llvm::opt::ArgList &Args,
return "rv64imafdc";
}
- // 3. Choose a default based on the triple
+ // 4. Choose a default based on the triple
//
// We deviate from GCC's defaults here:
// - On `riscv{XLEN}-unknown-elf` we default to `rv{XLEN}imac`
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 1cac5a0822a4..6b6e276b8ce7 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -333,6 +333,11 @@ std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T,
return TargetCPUName;
}
+ case llvm::Triple::riscv32:
+ case llvm::Triple::riscv64:
+ if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
+ return A->getValue();
+ return "";
case llvm::Triple::bpfel:
case llvm::Triple::bpfeb:
diff --git a/clang/test/Driver/riscv-arch.c b/clang/test/Driver/riscv-arch.c
index 13d0748a967a..725201a77ba7 100644
--- a/clang/test/Driver/riscv-arch.c
+++ b/clang/test/Driver/riscv-arch.c
@@ -156,9 +156,9 @@
// RV32-LOWER: error: invalid arch name 'rv32imC',
// RV32-LOWER: string must be lowercase
-// RUN: %clang -target riscv32-unknown-elf -march=rv32 -### %s \
+// RUN: %clang -target riscv32-unknown-elf -march=unknown -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-STR %s
-// RV32-STR: error: invalid arch name 'rv32',
+// RV32-STR: error: invalid arch name 'unknown',
// RV32-STR: string must begin with rv32{i,e,g} or rv64{i,g}
// RUN: %clang -target riscv32-unknown-elf -march=rv32q -### %s \
diff --git a/clang/test/Driver/riscv-cpus.c b/clang/test/Driver/riscv-cpus.c
new file mode 100644
index 000000000000..c6281a0b6433
--- /dev/null
+++ b/clang/test/Driver/riscv-cpus.c
@@ -0,0 +1,38 @@
+// Check target CPUs are correctly passed.
+
+// RUN: %clang -target riscv32 -### -c %s 2>&1 -mcpu=rocket-rv32 | FileCheck -check-prefix=MCPU-ROCKETCHIP32 %s
+// MCPU-ROCKETCHIP32: "-nostdsysteminc" "-target-cpu" "rocket-rv32"
+
+// RUN: %clang -target riscv64 -### -c %s 2>&1 -mcpu=rocket-rv64 | FileCheck -check-prefix=MCPU-ROCKETCHIP64 %s
+// MCPU-ROCKETCHIP64: "-nostdsysteminc" "-target-cpu" "rocket-rv64"
+// MCPU-ROCKETCHIP64: "-target-feature" "+64bit"
+
+// mcpu with default march
+// RUN: %clang -target riscv64 -### -c %s 2>&1 -mcpu=sifive-u54 | FileCheck -check-prefix=MCPU-SIFIVE-U54 %s
+// MCPU-SIFIVE-U54: "-nostdsysteminc" "-target-cpu" "sifive-u54"
+// MCPU-SIFIVE-U54: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f" "-target-feature" "+d"
+// MCPU-SIFIVE-U54: "-target-feature" "+c" "-target-feature" "+64bit"
+// MCPU-SIFIVE-U54: "-target-abi" "lp64d"
+
+// mcpu with mabi option
+// RUN: %clang -target riscv64 -### -c %s 2>&1 -mcpu=sifive-u54 -mabi=lp64 | FileCheck -check-prefix=MCPU-ABI-SIFIVE-U54 %s
+// MCPU-ABI-SIFIVE-U54: "-nostdsysteminc" "-target-cpu" "sifive-u54"
+// MCPU-ABI-SIFIVE-U54: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f" "-target-feature" "+d"
+// MCPU-ABI-SIFIVE-U54: "-target-feature" "+c" "-target-feature" "+64bit"
+// MCPU-ABI-SIFIVE-U54: "-target-abi" "lp64"
+
+// march overwirte mcpu's default march
+// RUN: %clang -target riscv32 -### -c %s 2>&1 -mcpu=sifive-e31 -march=rv32imc | FileCheck -check-prefix=MCPU-MARCH %s
+// MCPU-MARCH: "-nostdsysteminc" "-target-cpu" "sifive-e31" "-target-feature" "+m" "-target-feature" "+c"
+// MCPU-MARCH: "-target-abi" "ilp32"
+
+// Check failed cases
+
+// RUN: %clang -target riscv32 -### -c %s 2>&1 -mcpu=generic-rv321 | FileCheck -check-prefix=FAIL-MCPU-NAME %s
+// FAIL-MCPU-NAME: error: the clang compiler does not support '-mcpu=generic-rv321'
+
+// RUN: %clang -target riscv32 -### -c %s 2>&1 -mcpu=generic-rv32 -march=rv64i | FileCheck -check-prefix=MISMATCH-ARCH %s
+// MISMATCH-ARCH: error: the clang compiler does not support '-mcpu=generic-rv32'
+
+// RUN: %clang -target riscv32 -### -c %s 2>&1 -mcpu=generic-rv64 | FileCheck -check-prefix=MISMATCH-MCPU %s
+// MISMATCH-MCPU: error: the clang compiler does not support '-mcpu=generic-rv64'
diff --git a/clang/test/Misc/target-invalid-cpu-note.c b/clang/test/Misc/target-invalid-cpu-note.c
index 5c571fb458ec..3a376a7caab4 100644
--- a/clang/test/Misc/target-invalid-cpu-note.c
+++ b/clang/test/Misc/target-invalid-cpu-note.c
@@ -156,3 +156,10 @@
// AVR-SAME: ttiny4, attiny5, attiny9, attiny10, attiny20, attiny40, attiny102,
// AVR-SAME: attiny104
+// RUN: not %clang_cc1 -triple riscv32 -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix RISCV32
+// RISCV32: error: unknown target CPU 'not-a-cpu'
+// RISCV32: note: valid target CPU values are: generic-rv32, rocket-rv32, sifive-e31
+
+// RUN: not %clang_cc1 -triple riscv64 -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix RISCV64
+// RISCV64: error: unknown target CPU 'not-a-cpu'
+// RISCV64: note: valid target CPU values are: generic-rv64, rocket-rv64, sifive-u54
diff --git a/llvm/include/llvm/Support/RISCVTargetParser.def b/llvm/include/llvm/Support/RISCVTargetParser.def
new file mode 100644
index 000000000000..28de6cd40132
--- /dev/null
+++ b/llvm/include/llvm/Support/RISCVTargetParser.def
@@ -0,0 +1,13 @@
+#ifndef PROC
+#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH)
+#endif
+
+PROC(INVALID, {"invalid"}, FK_INVALID, {""})
+PROC(GENERIC_RV32, {"generic-rv32"}, FK_NONE, {""})
+PROC(GENERIC_RV64, {"generic-rv64"}, FK_64BIT, {""})
+PROC(ROCKET_RV32, {"rocket-rv32"}, FK_NONE, {""})
+PROC(ROCKET_RV64, {"rocket-rv64"}, FK_64BIT, {""})
+PROC(SIFIVE_E31, {"sifive-e31"}, FK_NONE, {"rv32imac"})
+PROC(SIFIVE_U54, {"sifive-u54"}, FK_64BIT, {"rv64gc"})
+
+#undef PROC
diff --git a/llvm/include/llvm/Support/TargetParser.h b/llvm/include/llvm/Support/TargetParser.h
index a0bd88c153b6..f521d8f836b4 100644
--- a/llvm/include/llvm/Support/TargetParser.h
+++ b/llvm/include/llvm/Support/TargetParser.h
@@ -130,6 +130,32 @@ IsaVersion getIsaVersion(StringRef GPU);
} // namespace AMDGPU
+namespace RISCV {
+
+enum CPUKind : unsigned {
+#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) CK_##ENUM,
+#include "RISCVTargetParser.def"
+};
+
+enum FeatureKind : unsigned {
+ FK_INVALID = 0,
+ FK_NONE = 1,
+ FK_STDEXTM = 1 << 2,
+ FK_STDEXTA = 1 << 3,
+ FK_STDEXTF = 1 << 4,
+ FK_STDEXTD = 1 << 5,
+ FK_STDEXTC = 1 << 6,
+ FK_64BIT = 1 << 7,
+};
+
+bool checkCPUKind(CPUKind Kind, bool IsRV64);
+CPUKind parseCPUKind(StringRef CPU);
+StringRef getMArchFromMcpu(StringRef CPU);
+void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64);
+bool getCPUFeaturesExceptStdExt(CPUKind Kind, std::vector<StringRef> &Features);
+
+} // namespace RISCV
+
} // namespace llvm
#endif
diff --git a/llvm/lib/Support/TargetParser.cpp b/llvm/lib/Support/TargetParser.cpp
index be9b541237c7..031384ebaa91 100644
--- a/llvm/lib/Support/TargetParser.cpp
+++ b/llvm/lib/Support/TargetParser.cpp
@@ -11,11 +11,12 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/TargetParser.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/Support/ARMBuildAttributes.h"
using namespace llvm;
using namespace AMDGPU;
@@ -208,3 +209,64 @@ AMDGPU::IsaVersion AMDGPU::getIsaVersion(StringRef GPU) {
default: return {0, 0, 0};
}
}
+
+namespace llvm {
+namespace RISCV {
+
+struct CPUInfo {
+ StringLiteral Name;
+ CPUKind Kind;
+ unsigned Features;
+ StringLiteral DefaultMarch;
+ bool is64Bit() const { return (Features & FK_64BIT); }
+};
+
+constexpr CPUInfo RISCVCPUInfo[] = {
+#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) \
+ {NAME, CK_##ENUM, FEATURES, DEFAULT_MARCH},
+#include "llvm/Support/RISCVTargetParser.def"
+};
+
+bool checkCPUKind(CPUKind Kind, bool IsRV64) {
+ if (Kind == CK_INVALID)
+ return false;
+ return RISCVCPUInfo[static_cast<unsigned>(Kind)].is64Bit() == IsRV64;
+}
+
+CPUKind parseCPUKind(StringRef CPU) {
+ return llvm::StringSwitch<CPUKind>(CPU)
+#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) .Case(NAME, CK_##ENUM)
+#include "llvm/Support/RISCVTargetParser.def"
+ .Default(CK_INVALID);
+}
+
+StringRef getMArchFromMcpu(StringRef CPU) {
+ CPUKind Kind = parseCPUKind(CPU);
+ return RISCVCPUInfo[static_cast<unsigned>(Kind)].DefaultMarch;
+}
+
+void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) {
+ for (const auto &C : RISCVCPUInfo) {
+ if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit())
+ Values.emplace_back(C.Name);
+ }
+}
+
+// Get all features except standard extension feature
+bool getCPUFeaturesExceptStdExt(CPUKind Kind,
+ std::vector<StringRef> &Features) {
+ unsigned CPUFeatures = RISCVCPUInfo[static_cast<unsigned>(Kind)].Features;
+
+ if (CPUFeatures == FK_INVALID)
+ return false;
+
+ if (CPUFeatures & FK_64BIT)
+ Features.push_back("+64bit");
+ else
+ Features.push_back("-64bit");
+
+ return true;
+}
+
+} // namespace RISCV
+} // namespace llvm
diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td
index f0583f691936..57e7c41c4271 100644
--- a/llvm/lib/Target/RISCV/RISCV.td
+++ b/llvm/lib/Target/RISCV/RISCV.td
@@ -215,6 +215,16 @@ def : ProcessorModel<"rocket-rv32", Rocket32Model, []>;
def : ProcessorModel<"rocket-rv64", Rocket64Model, [Feature64Bit]>;
+def : ProcessorModel<"sifive-e31", Rocket32Model, [FeatureStdExtM,
+ FeatureStdExtA,
+ FeatureStdExtC]>;
+
+def : ProcessorModel<"sifive-u54", Rocket64Model, [Feature64Bit,
+ FeatureStdExtM,
+ FeatureStdExtA,
+ FeatureStdExtF,
+ FeatureStdExtD,
+ FeatureStdExtC]>;
//===----------------------------------------------------------------------===//
// Define the RISC-V target.
More information about the llvm-commits
mailing list