1e5dd7070Spatrick //===--- RISCV.cpp - Implement RISCV target feature support ---------------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This file implements RISCV TargetInfo objects.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick
13e5dd7070Spatrick #include "RISCV.h"
14*7a9b00ceSrobert #include "clang/Basic/Diagnostic.h"
15e5dd7070Spatrick #include "clang/Basic/MacroBuilder.h"
16a0747c9fSpatrick #include "clang/Basic/TargetBuiltins.h"
17e5dd7070Spatrick #include "llvm/ADT/StringSwitch.h"
18*7a9b00ceSrobert #include "llvm/Support/raw_ostream.h"
19*7a9b00ceSrobert #include "llvm/TargetParser/RISCVTargetParser.h"
20*7a9b00ceSrobert #include <optional>
21e5dd7070Spatrick
22e5dd7070Spatrick using namespace clang;
23e5dd7070Spatrick using namespace clang::targets;
24e5dd7070Spatrick
getGCCRegNames() const25e5dd7070Spatrick ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const {
26e5dd7070Spatrick static const char *const GCCRegNames[] = {
27e5dd7070Spatrick // Integer registers
28e5dd7070Spatrick "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
29e5dd7070Spatrick "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
30e5dd7070Spatrick "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
31e5dd7070Spatrick "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31",
32e5dd7070Spatrick
33e5dd7070Spatrick // Floating point registers
34e5dd7070Spatrick "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
35e5dd7070Spatrick "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
36e5dd7070Spatrick "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
37a0747c9fSpatrick "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
38a0747c9fSpatrick
39a0747c9fSpatrick // Vector registers
40a0747c9fSpatrick "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
41a0747c9fSpatrick "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
42a0747c9fSpatrick "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
43a0747c9fSpatrick "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"};
44*7a9b00ceSrobert return llvm::ArrayRef(GCCRegNames);
45e5dd7070Spatrick }
46e5dd7070Spatrick
getGCCRegAliases() const47e5dd7070Spatrick ArrayRef<TargetInfo::GCCRegAlias> RISCVTargetInfo::getGCCRegAliases() const {
48e5dd7070Spatrick static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
49e5dd7070Spatrick {{"zero"}, "x0"}, {{"ra"}, "x1"}, {{"sp"}, "x2"}, {{"gp"}, "x3"},
50e5dd7070Spatrick {{"tp"}, "x4"}, {{"t0"}, "x5"}, {{"t1"}, "x6"}, {{"t2"}, "x7"},
51e5dd7070Spatrick {{"s0"}, "x8"}, {{"s1"}, "x9"}, {{"a0"}, "x10"}, {{"a1"}, "x11"},
52e5dd7070Spatrick {{"a2"}, "x12"}, {{"a3"}, "x13"}, {{"a4"}, "x14"}, {{"a5"}, "x15"},
53e5dd7070Spatrick {{"a6"}, "x16"}, {{"a7"}, "x17"}, {{"s2"}, "x18"}, {{"s3"}, "x19"},
54e5dd7070Spatrick {{"s4"}, "x20"}, {{"s5"}, "x21"}, {{"s6"}, "x22"}, {{"s7"}, "x23"},
55e5dd7070Spatrick {{"s8"}, "x24"}, {{"s9"}, "x25"}, {{"s10"}, "x26"}, {{"s11"}, "x27"},
56e5dd7070Spatrick {{"t3"}, "x28"}, {{"t4"}, "x29"}, {{"t5"}, "x30"}, {{"t6"}, "x31"},
57e5dd7070Spatrick {{"ft0"}, "f0"}, {{"ft1"}, "f1"}, {{"ft2"}, "f2"}, {{"ft3"}, "f3"},
58e5dd7070Spatrick {{"ft4"}, "f4"}, {{"ft5"}, "f5"}, {{"ft6"}, "f6"}, {{"ft7"}, "f7"},
59e5dd7070Spatrick {{"fs0"}, "f8"}, {{"fs1"}, "f9"}, {{"fa0"}, "f10"}, {{"fa1"}, "f11"},
60e5dd7070Spatrick {{"fa2"}, "f12"}, {{"fa3"}, "f13"}, {{"fa4"}, "f14"}, {{"fa5"}, "f15"},
61e5dd7070Spatrick {{"fa6"}, "f16"}, {{"fa7"}, "f17"}, {{"fs2"}, "f18"}, {{"fs3"}, "f19"},
62e5dd7070Spatrick {{"fs4"}, "f20"}, {{"fs5"}, "f21"}, {{"fs6"}, "f22"}, {{"fs7"}, "f23"},
63e5dd7070Spatrick {{"fs8"}, "f24"}, {{"fs9"}, "f25"}, {{"fs10"}, "f26"}, {{"fs11"}, "f27"},
64e5dd7070Spatrick {{"ft8"}, "f28"}, {{"ft9"}, "f29"}, {{"ft10"}, "f30"}, {{"ft11"}, "f31"}};
65*7a9b00ceSrobert return llvm::ArrayRef(GCCRegAliases);
66e5dd7070Spatrick }
67e5dd7070Spatrick
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const68e5dd7070Spatrick bool RISCVTargetInfo::validateAsmConstraint(
69e5dd7070Spatrick const char *&Name, TargetInfo::ConstraintInfo &Info) const {
70e5dd7070Spatrick switch (*Name) {
71e5dd7070Spatrick default:
72e5dd7070Spatrick return false;
73e5dd7070Spatrick case 'I':
74e5dd7070Spatrick // A 12-bit signed immediate.
75e5dd7070Spatrick Info.setRequiresImmediate(-2048, 2047);
76e5dd7070Spatrick return true;
77e5dd7070Spatrick case 'J':
78e5dd7070Spatrick // Integer zero.
79e5dd7070Spatrick Info.setRequiresImmediate(0);
80e5dd7070Spatrick return true;
81e5dd7070Spatrick case 'K':
82e5dd7070Spatrick // A 5-bit unsigned immediate for CSR access instructions.
83e5dd7070Spatrick Info.setRequiresImmediate(0, 31);
84e5dd7070Spatrick return true;
85e5dd7070Spatrick case 'f':
86e5dd7070Spatrick // A floating-point register.
87e5dd7070Spatrick Info.setAllowsRegister();
88e5dd7070Spatrick return true;
89e5dd7070Spatrick case 'A':
90e5dd7070Spatrick // An address that is held in a general-purpose register.
91e5dd7070Spatrick Info.setAllowsMemory();
92e5dd7070Spatrick return true;
93a0747c9fSpatrick case 'S': // A symbolic address
94a0747c9fSpatrick Info.setAllowsRegister();
95a0747c9fSpatrick return true;
96a0747c9fSpatrick case 'v':
97a0747c9fSpatrick // A vector register.
98a0747c9fSpatrick if (Name[1] == 'r' || Name[1] == 'm') {
99a0747c9fSpatrick Info.setAllowsRegister();
100a0747c9fSpatrick Name += 1;
101a0747c9fSpatrick return true;
102e5dd7070Spatrick }
103a0747c9fSpatrick return false;
104a0747c9fSpatrick }
105a0747c9fSpatrick }
106a0747c9fSpatrick
convertConstraint(const char * & Constraint) const107a0747c9fSpatrick std::string RISCVTargetInfo::convertConstraint(const char *&Constraint) const {
108a0747c9fSpatrick std::string R;
109a0747c9fSpatrick switch (*Constraint) {
110a0747c9fSpatrick case 'v':
111*7a9b00ceSrobert R = std::string("^") + std::string(Constraint, 2);
112a0747c9fSpatrick Constraint += 1;
113a0747c9fSpatrick break;
114a0747c9fSpatrick default:
115a0747c9fSpatrick R = TargetInfo::convertConstraint(Constraint);
116a0747c9fSpatrick break;
117a0747c9fSpatrick }
118a0747c9fSpatrick return R;
119e5dd7070Spatrick }
120e5dd7070Spatrick
getVersionValue(unsigned MajorVersion,unsigned MinorVersion)121*7a9b00ceSrobert static unsigned getVersionValue(unsigned MajorVersion, unsigned MinorVersion) {
122*7a9b00ceSrobert return MajorVersion * 1000000 + MinorVersion * 1000;
123*7a9b00ceSrobert }
124*7a9b00ceSrobert
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const125e5dd7070Spatrick void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
126e5dd7070Spatrick MacroBuilder &Builder) const {
127e5dd7070Spatrick Builder.defineMacro("__ELF__");
128e5dd7070Spatrick Builder.defineMacro("__riscv");
129e5dd7070Spatrick bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64;
130e5dd7070Spatrick Builder.defineMacro("__riscv_xlen", Is64Bit ? "64" : "32");
131e5dd7070Spatrick StringRef CodeModel = getTargetOpts().CodeModel;
132*7a9b00ceSrobert unsigned FLen = ISAInfo->getFLen();
133*7a9b00ceSrobert unsigned MinVLen = ISAInfo->getMinVLen();
134*7a9b00ceSrobert unsigned MaxELen = ISAInfo->getMaxELen();
135*7a9b00ceSrobert unsigned MaxELenFp = ISAInfo->getMaxELenFp();
136e5dd7070Spatrick if (CodeModel == "default")
137e5dd7070Spatrick CodeModel = "small";
138e5dd7070Spatrick
139e5dd7070Spatrick if (CodeModel == "small")
140e5dd7070Spatrick Builder.defineMacro("__riscv_cmodel_medlow");
141e5dd7070Spatrick else if (CodeModel == "medium")
142e5dd7070Spatrick Builder.defineMacro("__riscv_cmodel_medany");
143e5dd7070Spatrick
144e5dd7070Spatrick StringRef ABIName = getABI();
145e5dd7070Spatrick if (ABIName == "ilp32f" || ABIName == "lp64f")
146e5dd7070Spatrick Builder.defineMacro("__riscv_float_abi_single");
147e5dd7070Spatrick else if (ABIName == "ilp32d" || ABIName == "lp64d")
148e5dd7070Spatrick Builder.defineMacro("__riscv_float_abi_double");
149e5dd7070Spatrick else
150e5dd7070Spatrick Builder.defineMacro("__riscv_float_abi_soft");
151e5dd7070Spatrick
152e5dd7070Spatrick if (ABIName == "ilp32e")
153e5dd7070Spatrick Builder.defineMacro("__riscv_abi_rve");
154e5dd7070Spatrick
155a0747c9fSpatrick Builder.defineMacro("__riscv_arch_test");
156a0747c9fSpatrick
157*7a9b00ceSrobert for (auto &Extension : ISAInfo->getExtensions()) {
158*7a9b00ceSrobert auto ExtName = Extension.first;
159*7a9b00ceSrobert auto ExtInfo = Extension.second;
160*7a9b00ceSrobert
161*7a9b00ceSrobert Builder.defineMacro(
162*7a9b00ceSrobert Twine("__riscv_", ExtName),
163*7a9b00ceSrobert Twine(getVersionValue(ExtInfo.MajorVersion, ExtInfo.MinorVersion)));
164*7a9b00ceSrobert }
165*7a9b00ceSrobert
166*7a9b00ceSrobert if (ISAInfo->hasExtension("m") || ISAInfo->hasExtension("zmmul"))
167e5dd7070Spatrick Builder.defineMacro("__riscv_mul");
168*7a9b00ceSrobert
169*7a9b00ceSrobert if (ISAInfo->hasExtension("m")) {
170e5dd7070Spatrick Builder.defineMacro("__riscv_div");
171e5dd7070Spatrick Builder.defineMacro("__riscv_muldiv");
172e5dd7070Spatrick }
173e5dd7070Spatrick
174*7a9b00ceSrobert if (ISAInfo->hasExtension("a")) {
175e5dd7070Spatrick Builder.defineMacro("__riscv_atomic");
176af2320b8Sderaadt Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
177af2320b8Sderaadt Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
178af2320b8Sderaadt Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
179af2320b8Sderaadt if (Is64Bit)
180af2320b8Sderaadt Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
181af2320b8Sderaadt }
182e5dd7070Spatrick
183*7a9b00ceSrobert if (FLen) {
184*7a9b00ceSrobert Builder.defineMacro("__riscv_flen", Twine(FLen));
185e5dd7070Spatrick Builder.defineMacro("__riscv_fdiv");
186e5dd7070Spatrick Builder.defineMacro("__riscv_fsqrt");
187e5dd7070Spatrick }
188e5dd7070Spatrick
189*7a9b00ceSrobert if (MinVLen) {
190*7a9b00ceSrobert Builder.defineMacro("__riscv_v_min_vlen", Twine(MinVLen));
191*7a9b00ceSrobert Builder.defineMacro("__riscv_v_elen", Twine(MaxELen));
192*7a9b00ceSrobert Builder.defineMacro("__riscv_v_elen_fp", Twine(MaxELenFp));
193*7a9b00ceSrobert }
194ec727ea7Spatrick
195*7a9b00ceSrobert if (ISAInfo->hasExtension("c"))
196a0747c9fSpatrick Builder.defineMacro("__riscv_compressed");
197a0747c9fSpatrick
198*7a9b00ceSrobert if (ISAInfo->hasExtension("zve32x")) {
199a0747c9fSpatrick Builder.defineMacro("__riscv_vector");
200*7a9b00ceSrobert // Currently we support the v0.11 RISC-V V intrinsics.
201*7a9b00ceSrobert Builder.defineMacro("__riscv_v_intrinsic", Twine(getVersionValue(0, 11)));
202*7a9b00ceSrobert }
203a0747c9fSpatrick }
204a0747c9fSpatrick
205*7a9b00ceSrobert static constexpr Builtin::Info BuiltinInfo[] = {
206a0747c9fSpatrick #define BUILTIN(ID, TYPE, ATTRS) \
207*7a9b00ceSrobert {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
208a0747c9fSpatrick #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
209*7a9b00ceSrobert {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
210*7a9b00ceSrobert #include "clang/Basic/BuiltinsRISCVVector.def"
211*7a9b00ceSrobert #define BUILTIN(ID, TYPE, ATTRS) \
212*7a9b00ceSrobert {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
213*7a9b00ceSrobert #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
214*7a9b00ceSrobert {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
215a0747c9fSpatrick #include "clang/Basic/BuiltinsRISCV.def"
216a0747c9fSpatrick };
217a0747c9fSpatrick
getTargetBuiltins() const218a0747c9fSpatrick ArrayRef<Builtin::Info> RISCVTargetInfo::getTargetBuiltins() const {
219*7a9b00ceSrobert return llvm::ArrayRef(BuiltinInfo,
220*7a9b00ceSrobert clang::RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin);
221a0747c9fSpatrick }
222a0747c9fSpatrick
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec) const223a0747c9fSpatrick bool RISCVTargetInfo::initFeatureMap(
224a0747c9fSpatrick llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
225a0747c9fSpatrick const std::vector<std::string> &FeaturesVec) const {
226a0747c9fSpatrick
227*7a9b00ceSrobert unsigned XLen = 32;
228a0747c9fSpatrick
229*7a9b00ceSrobert if (getTriple().getArch() == llvm::Triple::riscv64) {
230*7a9b00ceSrobert Features["64bit"] = true;
231*7a9b00ceSrobert XLen = 64;
232*7a9b00ceSrobert } else {
233*7a9b00ceSrobert Features["32bit"] = true;
234*7a9b00ceSrobert }
235*7a9b00ceSrobert
236*7a9b00ceSrobert auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesVec);
237*7a9b00ceSrobert if (!ParseResult) {
238*7a9b00ceSrobert std::string Buffer;
239*7a9b00ceSrobert llvm::raw_string_ostream OutputErrMsg(Buffer);
240*7a9b00ceSrobert handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
241*7a9b00ceSrobert OutputErrMsg << ErrMsg.getMessage();
242*7a9b00ceSrobert });
243*7a9b00ceSrobert Diags.Report(diag::err_invalid_feature_combination) << OutputErrMsg.str();
244*7a9b00ceSrobert return false;
245*7a9b00ceSrobert }
246*7a9b00ceSrobert
247*7a9b00ceSrobert // RISCVISAInfo makes implications for ISA features
248*7a9b00ceSrobert std::vector<std::string> ImpliedFeatures = (*ParseResult)->toFeatureVector();
249*7a9b00ceSrobert // Add non-ISA features like `relax` and `save-restore` back
250*7a9b00ceSrobert for (const std::string &Feature : FeaturesVec)
251*7a9b00ceSrobert if (!llvm::is_contained(ImpliedFeatures, Feature))
252*7a9b00ceSrobert ImpliedFeatures.push_back(Feature);
253*7a9b00ceSrobert
254*7a9b00ceSrobert return TargetInfo::initFeatureMap(Features, Diags, CPU, ImpliedFeatures);
255*7a9b00ceSrobert }
256*7a9b00ceSrobert
257*7a9b00ceSrobert std::optional<std::pair<unsigned, unsigned>>
getVScaleRange(const LangOptions & LangOpts) const258*7a9b00ceSrobert RISCVTargetInfo::getVScaleRange(const LangOptions &LangOpts) const {
259*7a9b00ceSrobert // RISCV::RVVBitsPerBlock is 64.
260*7a9b00ceSrobert unsigned VScaleMin = ISAInfo->getMinVLen() / llvm::RISCV::RVVBitsPerBlock;
261*7a9b00ceSrobert
262*7a9b00ceSrobert if (LangOpts.VScaleMin || LangOpts.VScaleMax) {
263*7a9b00ceSrobert // Treat Zvl*b as a lower bound on vscale.
264*7a9b00ceSrobert VScaleMin = std::max(VScaleMin, LangOpts.VScaleMin);
265*7a9b00ceSrobert unsigned VScaleMax = LangOpts.VScaleMax;
266*7a9b00ceSrobert if (VScaleMax != 0 && VScaleMax < VScaleMin)
267*7a9b00ceSrobert VScaleMax = VScaleMin;
268*7a9b00ceSrobert return std::pair<unsigned, unsigned>(VScaleMin ? VScaleMin : 1, VScaleMax);
269*7a9b00ceSrobert }
270*7a9b00ceSrobert
271*7a9b00ceSrobert if (VScaleMin > 0) {
272*7a9b00ceSrobert unsigned VScaleMax = ISAInfo->getMaxVLen() / llvm::RISCV::RVVBitsPerBlock;
273*7a9b00ceSrobert return std::make_pair(VScaleMin, VScaleMax);
274*7a9b00ceSrobert }
275*7a9b00ceSrobert
276*7a9b00ceSrobert return std::nullopt;
277a0747c9fSpatrick }
278a0747c9fSpatrick
279e5dd7070Spatrick /// Return true if has this feature, need to sync with handleTargetFeatures.
hasFeature(StringRef Feature) const280e5dd7070Spatrick bool RISCVTargetInfo::hasFeature(StringRef Feature) const {
281e5dd7070Spatrick bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64;
282*7a9b00ceSrobert auto Result = llvm::StringSwitch<std::optional<bool>>(Feature)
283e5dd7070Spatrick .Case("riscv", true)
284e5dd7070Spatrick .Case("riscv32", !Is64Bit)
285e5dd7070Spatrick .Case("riscv64", Is64Bit)
286*7a9b00ceSrobert .Case("32bit", !Is64Bit)
287a0747c9fSpatrick .Case("64bit", Is64Bit)
288*7a9b00ceSrobert .Default(std::nullopt);
289*7a9b00ceSrobert if (Result)
290*7a9b00ceSrobert return *Result;
291*7a9b00ceSrobert
292*7a9b00ceSrobert if (ISAInfo->isSupportedExtensionFeature(Feature))
293*7a9b00ceSrobert return ISAInfo->hasExtension(Feature);
294*7a9b00ceSrobert
295*7a9b00ceSrobert return false;
296e5dd7070Spatrick }
297e5dd7070Spatrick
298e5dd7070Spatrick /// Perform initialization based on the user configured set of features.
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)299e5dd7070Spatrick bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
300e5dd7070Spatrick DiagnosticsEngine &Diags) {
301*7a9b00ceSrobert unsigned XLen = getTriple().isArch64Bit() ? 64 : 32;
302*7a9b00ceSrobert auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, Features);
303*7a9b00ceSrobert if (!ParseResult) {
304*7a9b00ceSrobert std::string Buffer;
305*7a9b00ceSrobert llvm::raw_string_ostream OutputErrMsg(Buffer);
306*7a9b00ceSrobert handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
307*7a9b00ceSrobert OutputErrMsg << ErrMsg.getMessage();
308*7a9b00ceSrobert });
309*7a9b00ceSrobert Diags.Report(diag::err_invalid_feature_combination) << OutputErrMsg.str();
310*7a9b00ceSrobert return false;
311*7a9b00ceSrobert } else {
312*7a9b00ceSrobert ISAInfo = std::move(*ParseResult);
313e5dd7070Spatrick }
314e5dd7070Spatrick
315*7a9b00ceSrobert if (ABI.empty())
316*7a9b00ceSrobert ABI = ISAInfo->computeDefaultABI().str();
317*7a9b00ceSrobert
318e5dd7070Spatrick return true;
319e5dd7070Spatrick }
320ec727ea7Spatrick
isValidCPUName(StringRef Name) const321*7a9b00ceSrobert bool RISCVTargetInfo::isValidCPUName(StringRef Name) const {
322*7a9b00ceSrobert bool Is64Bit = getTriple().isArch64Bit();
323*7a9b00ceSrobert return llvm::RISCV::checkCPUKind(llvm::RISCV::parseCPUKind(Name), Is64Bit);
324ec727ea7Spatrick }
325ec727ea7Spatrick
fillValidCPUList(SmallVectorImpl<StringRef> & Values) const326*7a9b00ceSrobert void RISCVTargetInfo::fillValidCPUList(
327ec727ea7Spatrick SmallVectorImpl<StringRef> &Values) const {
328*7a9b00ceSrobert bool Is64Bit = getTriple().isArch64Bit();
329*7a9b00ceSrobert llvm::RISCV::fillValidCPUArchList(Values, Is64Bit);
330ec727ea7Spatrick }
331ec727ea7Spatrick
isValidTuneCPUName(StringRef Name) const332*7a9b00ceSrobert bool RISCVTargetInfo::isValidTuneCPUName(StringRef Name) const {
333*7a9b00ceSrobert bool Is64Bit = getTriple().isArch64Bit();
334a0747c9fSpatrick return llvm::RISCV::checkTuneCPUKind(
335*7a9b00ceSrobert llvm::RISCV::parseTuneCPUKind(Name, Is64Bit), Is64Bit);
336a0747c9fSpatrick }
337a0747c9fSpatrick
fillValidTuneCPUList(SmallVectorImpl<StringRef> & Values) const338*7a9b00ceSrobert void RISCVTargetInfo::fillValidTuneCPUList(
339a0747c9fSpatrick SmallVectorImpl<StringRef> &Values) const {
340*7a9b00ceSrobert bool Is64Bit = getTriple().isArch64Bit();
341*7a9b00ceSrobert llvm::RISCV::fillValidTuneCPUArchList(Values, Is64Bit);
342a0747c9fSpatrick }
343