clang 22.0.0git
RISCV.cpp
Go to the documentation of this file.
1//===--- RISCV.cpp - Implement RISC-V target feature support --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements RISC-V TargetInfo objects.
10//
11//===----------------------------------------------------------------------===//
12
13#include "RISCV.h"
17#include "llvm/ADT/StringSwitch.h"
18#include "llvm/Support/raw_ostream.h"
19#include "llvm/TargetParser/RISCVTargetParser.h"
20#include <optional>
21
22using namespace clang;
23using namespace clang::targets;
24
26 // clang-format off
27 static const char *const GCCRegNames[] = {
28 // Integer registers
29 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
30 "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
31 "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
32 "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31",
33
34 // Floating point registers
35 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
36 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
37 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
38 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
39
40 // Vector registers
41 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
42 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
43 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
44 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
45
46 // CSRs
47 "fflags", "frm", "vtype", "vl", "vxsat", "vxrm", "sf.vcix_state"
48 };
49 // clang-format on
51}
52
54 static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
55 {{"zero"}, "x0"}, {{"ra"}, "x1"}, {{"sp"}, "x2"}, {{"gp"}, "x3"},
56 {{"tp"}, "x4"}, {{"t0"}, "x5"}, {{"t1"}, "x6"}, {{"t2"}, "x7"},
57 {{"s0"}, "x8"}, {{"s1"}, "x9"}, {{"a0"}, "x10"}, {{"a1"}, "x11"},
58 {{"a2"}, "x12"}, {{"a3"}, "x13"}, {{"a4"}, "x14"}, {{"a5"}, "x15"},
59 {{"a6"}, "x16"}, {{"a7"}, "x17"}, {{"s2"}, "x18"}, {{"s3"}, "x19"},
60 {{"s4"}, "x20"}, {{"s5"}, "x21"}, {{"s6"}, "x22"}, {{"s7"}, "x23"},
61 {{"s8"}, "x24"}, {{"s9"}, "x25"}, {{"s10"}, "x26"}, {{"s11"}, "x27"},
62 {{"t3"}, "x28"}, {{"t4"}, "x29"}, {{"t5"}, "x30"}, {{"t6"}, "x31"},
63 {{"ft0"}, "f0"}, {{"ft1"}, "f1"}, {{"ft2"}, "f2"}, {{"ft3"}, "f3"},
64 {{"ft4"}, "f4"}, {{"ft5"}, "f5"}, {{"ft6"}, "f6"}, {{"ft7"}, "f7"},
65 {{"fs0"}, "f8"}, {{"fs1"}, "f9"}, {{"fa0"}, "f10"}, {{"fa1"}, "f11"},
66 {{"fa2"}, "f12"}, {{"fa3"}, "f13"}, {{"fa4"}, "f14"}, {{"fa5"}, "f15"},
67 {{"fa6"}, "f16"}, {{"fa7"}, "f17"}, {{"fs2"}, "f18"}, {{"fs3"}, "f19"},
68 {{"fs4"}, "f20"}, {{"fs5"}, "f21"}, {{"fs6"}, "f22"}, {{"fs7"}, "f23"},
69 {{"fs8"}, "f24"}, {{"fs9"}, "f25"}, {{"fs10"}, "f26"}, {{"fs11"}, "f27"},
70 {{"ft8"}, "f28"}, {{"ft9"}, "f29"}, {{"ft10"}, "f30"}, {{"ft11"}, "f31"}};
71 return llvm::ArrayRef(GCCRegAliases);
72}
73
75 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
76 switch (*Name) {
77 default:
78 return false;
79 case 'I':
80 // A 12-bit signed immediate.
81 Info.setRequiresImmediate(-2048, 2047);
82 return true;
83 case 'J':
84 // Integer zero.
86 return true;
87 case 'K':
88 // A 5-bit unsigned immediate for CSR access instructions.
89 Info.setRequiresImmediate(0, 31);
90 return true;
91 case 'f':
92 // A floating-point register.
93 Info.setAllowsRegister();
94 return true;
95 case 'A':
96 // An address that is held in a general-purpose register.
97 Info.setAllowsMemory();
98 return true;
99 case 's':
100 case 'S': // A symbol or label reference with a constant offset
101 Info.setAllowsRegister();
102 return true;
103 case 'c':
104 // A RVC register - GPR or FPR
105 if (Name[1] == 'r' || Name[1] == 'R' || Name[1] == 'f') {
106 Info.setAllowsRegister();
107 Name += 1;
108 return true;
109 }
110 return false;
111 case 'R':
112 // An even-odd GPR pair
113 Info.setAllowsRegister();
114 return true;
115 case 'v':
116 // A vector register.
117 if (Name[1] == 'r' || Name[1] == 'd' || Name[1] == 'm') {
118 Info.setAllowsRegister();
119 Name += 1;
120 return true;
121 }
122 return false;
123 }
124}
125
126std::string RISCVTargetInfo::convertConstraint(const char *&Constraint) const {
127 std::string R;
128 switch (*Constraint) {
129 // c* and v* are two-letter constraints on RISC-V.
130 case 'c':
131 case 'v':
132 R = std::string("^") + std::string(Constraint, 2);
133 Constraint += 1;
134 break;
135 default:
136 R = TargetInfo::convertConstraint(Constraint);
137 break;
138 }
139 return R;
140}
141
142static unsigned getVersionValue(unsigned MajorVersion, unsigned MinorVersion) {
143 return MajorVersion * 1000000 + MinorVersion * 1000;
144}
145
147 MacroBuilder &Builder) const {
148 Builder.defineMacro("__riscv");
149 bool Is64Bit = getTriple().isRISCV64();
150 Builder.defineMacro("__riscv_xlen", Is64Bit ? "64" : "32");
151 StringRef CodeModel = getTargetOpts().CodeModel;
152 unsigned FLen = ISAInfo->getFLen();
153 unsigned MinVLen = ISAInfo->getMinVLen();
154 unsigned MaxELen = ISAInfo->getMaxELen();
155 unsigned MaxELenFp = ISAInfo->getMaxELenFp();
156 if (CodeModel == "default")
157 CodeModel = "small";
158
159 if (CodeModel == "small")
160 Builder.defineMacro("__riscv_cmodel_medlow");
161 else if (CodeModel == "medium")
162 Builder.defineMacro("__riscv_cmodel_medany");
163 else if (CodeModel == "large")
164 Builder.defineMacro("__riscv_cmodel_large");
165
166 StringRef ABIName = getABI();
167 if (ABIName == "ilp32f" || ABIName == "lp64f")
168 Builder.defineMacro("__riscv_float_abi_single");
169 else if (ABIName == "ilp32d" || ABIName == "lp64d")
170 Builder.defineMacro("__riscv_float_abi_double");
171 else
172 Builder.defineMacro("__riscv_float_abi_soft");
173
174 if (ABIName == "ilp32e" || ABIName == "lp64e")
175 Builder.defineMacro("__riscv_abi_rve");
176
177 Builder.defineMacro("__riscv_arch_test");
178
179 for (auto &Extension : ISAInfo->getExtensions()) {
180 auto ExtName = Extension.first;
181 auto ExtInfo = Extension.second;
182
183 Builder.defineMacro(Twine("__riscv_", ExtName),
184 Twine(getVersionValue(ExtInfo.Major, ExtInfo.Minor)));
185 }
186
187 if (ISAInfo->hasExtension("zmmul"))
188 Builder.defineMacro("__riscv_mul");
189
190 if (ISAInfo->hasExtension("m")) {
191 Builder.defineMacro("__riscv_div");
192 Builder.defineMacro("__riscv_muldiv");
193 }
194
195 if (ISAInfo->hasExtension("a")) {
196 Builder.defineMacro("__riscv_atomic");
197 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
198 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
199 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
200 if (Is64Bit)
201 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
202 }
203
204 if (FLen) {
205 Builder.defineMacro("__riscv_flen", Twine(FLen));
206 Builder.defineMacro("__riscv_fdiv");
207 Builder.defineMacro("__riscv_fsqrt");
208 }
209
210 if (MinVLen) {
211 Builder.defineMacro("__riscv_v_min_vlen", Twine(MinVLen));
212 Builder.defineMacro("__riscv_v_elen", Twine(MaxELen));
213 Builder.defineMacro("__riscv_v_elen_fp", Twine(MaxELenFp));
214 }
215
216 if (ISAInfo->hasExtension("c"))
217 Builder.defineMacro("__riscv_compressed");
218
219 if (ISAInfo->hasExtension("zve32x"))
220 Builder.defineMacro("__riscv_vector");
221
222 // Currently we support the v1.0 RISC-V V intrinsics.
223 Builder.defineMacro("__riscv_v_intrinsic", Twine(getVersionValue(1, 0)));
224
226 if (VScale && VScale->first && VScale->first == VScale->second)
227 Builder.defineMacro("__riscv_v_fixed_vlen",
228 Twine(VScale->first * llvm::RISCV::RVVBitsPerBlock));
229
230 if (FastScalarUnalignedAccess)
231 Builder.defineMacro("__riscv_misaligned_fast");
232 else
233 Builder.defineMacro("__riscv_misaligned_avoid");
234
235 if (ISAInfo->hasExtension("e")) {
236 if (Is64Bit)
237 Builder.defineMacro("__riscv_64e");
238 else
239 Builder.defineMacro("__riscv_32e");
240 }
241
242 if (Opts.CFProtectionReturn && ISAInfo->hasExtension("zicfiss"))
243 Builder.defineMacro("__riscv_shadow_stack");
244
245 if (Opts.CFProtectionBranch) {
246 auto Scheme = Opts.getCFBranchLabelScheme();
249
250 Builder.defineMacro("__riscv_landing_pad");
251 switch (Scheme) {
252 case CFBranchLabelSchemeKind::Unlabeled:
253 Builder.defineMacro("__riscv_landing_pad_unlabeled");
254 break;
255 case CFBranchLabelSchemeKind::FuncSig:
256 // TODO: Define macros after the func-sig scheme is implemented
257 break;
259 llvm_unreachable("default cf-branch-label scheme should already be "
260 "transformed to other scheme");
261 }
262 }
263}
264
265static constexpr int NumRVVBuiltins =
267static constexpr int NumRVVSiFiveBuiltins =
269static constexpr int NumRVVAndesBuiltins =
271static constexpr int NumRISCVBuiltins =
273static constexpr int NumBuiltins =
277
278namespace RVV {
279#define GET_RISCVV_BUILTIN_STR_TABLE
280#include "clang/Basic/riscv_vector_builtins.inc"
281#undef GET_RISCVV_BUILTIN_STR_TABLE
282static_assert(BuiltinStrings.size() < 100'000);
283
284static constexpr std::array<Builtin::Info, NumRVVBuiltins> BuiltinInfos = {
285#define GET_RISCVV_BUILTIN_INFOS
286#include "clang/Basic/riscv_vector_builtins.inc"
287#undef GET_RISCVV_BUILTIN_INFOS
288};
289} // namespace RVV
290
291namespace RVVSiFive {
292#define GET_RISCVV_BUILTIN_STR_TABLE
293#include "clang/Basic/riscv_sifive_vector_builtins.inc"
294#undef GET_RISCVV_BUILTIN_STR_TABLE
295
296static constexpr std::array<Builtin::Info, NumRVVSiFiveBuiltins> BuiltinInfos =
297 {
298#define GET_RISCVV_BUILTIN_INFOS
299#include "clang/Basic/riscv_sifive_vector_builtins.inc"
300#undef GET_RISCVV_BUILTIN_INFOS
301};
302} // namespace RVVSiFive
303
304namespace RVVAndes {
305#define GET_RISCVV_BUILTIN_STR_TABLE
306#include "clang/Basic/riscv_andes_vector_builtins.inc"
307#undef GET_RISCVV_BUILTIN_STR_TABLE
308
309static constexpr std::array<Builtin::Info, NumRVVAndesBuiltins> BuiltinInfos =
310 {
311#define GET_RISCVV_BUILTIN_INFOS
312#include "clang/Basic/riscv_andes_vector_builtins.inc"
313#undef GET_RISCVV_BUILTIN_INFOS
314};
315} // namespace RVVAndes
316
317#define GET_BUILTIN_STR_TABLE
318#include "clang/Basic/BuiltinsRISCV.inc"
319#undef GET_BUILTIN_STR_TABLE
320
321static constexpr Builtin::Info BuiltinInfos[] = {
322#define GET_BUILTIN_INFOS
323#include "clang/Basic/BuiltinsRISCV.inc"
324#undef GET_BUILTIN_INFOS
325};
326static_assert(std::size(BuiltinInfos) == NumRISCVBuiltins);
327
328llvm::SmallVector<Builtin::InfosShard>
330 return {
331 {&RVV::BuiltinStrings, RVV::BuiltinInfos, "__builtin_rvv_"},
332 {&RVVSiFive::BuiltinStrings, RVVSiFive::BuiltinInfos, "__builtin_rvv_"},
333 {&RVVAndes::BuiltinStrings, RVVAndes::BuiltinInfos, "__builtin_rvv_"},
335 };
336}
337
339 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
340 const std::vector<std::string> &FeaturesVec) const {
341
342 unsigned XLen = 32;
343
344 if (getTriple().isRISCV64()) {
345 Features["64bit"] = true;
346 XLen = 64;
347 } else {
348 Features["32bit"] = true;
349 }
350
351 std::vector<std::string> AllFeatures = FeaturesVec;
352 auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesVec);
353 if (!ParseResult) {
354 std::string Buffer;
355 llvm::raw_string_ostream OutputErrMsg(Buffer);
356 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
357 OutputErrMsg << ErrMsg.getMessage();
358 });
359 Diags.Report(diag::err_invalid_feature_combination) << OutputErrMsg.str();
360 return false;
361 }
362
363 // Append all features, not just new ones, so we override any negatives.
364 llvm::append_range(AllFeatures, (*ParseResult)->toFeatures());
365 return TargetInfo::initFeatureMap(Features, Diags, CPU, AllFeatures);
366}
367
368std::optional<std::pair<unsigned, unsigned>>
371 llvm::StringMap<bool> *FeatureMap) const {
372 // RISCV::RVVBitsPerBlock is 64.
373 unsigned VScaleMin = ISAInfo->getMinVLen() / llvm::RISCV::RVVBitsPerBlock;
374
375 if (LangOpts.VScaleMin || LangOpts.VScaleMax) {
376 // Treat Zvl*b as a lower bound on vscale.
377 VScaleMin = std::max(VScaleMin, LangOpts.VScaleMin);
378 unsigned VScaleMax = LangOpts.VScaleMax;
379 if (VScaleMax != 0 && VScaleMax < VScaleMin)
380 VScaleMax = VScaleMin;
381 return std::pair<unsigned, unsigned>(VScaleMin ? VScaleMin : 1, VScaleMax);
382 }
383
384 if (VScaleMin > 0) {
385 unsigned VScaleMax = ISAInfo->getMaxVLen() / llvm::RISCV::RVVBitsPerBlock;
386 return std::make_pair(VScaleMin, VScaleMax);
387 }
388
389 return std::nullopt;
390}
391
392/// Return true if has this feature, need to sync with handleTargetFeatures.
394 bool Is64Bit = getTriple().isRISCV64();
395 auto Result = llvm::StringSwitch<std::optional<bool>>(Feature)
396 .Case("riscv", true)
397 .Case("riscv32", !Is64Bit)
398 .Case("riscv64", Is64Bit)
399 .Case("32bit", !Is64Bit)
400 .Case("64bit", Is64Bit)
401 .Case("experimental", HasExperimental)
402 .Default(std::nullopt);
403 if (Result)
404 return *Result;
405
406 return ISAInfo->hasExtension(Feature);
407}
408
409/// Perform initialization based on the user configured set of features.
410bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
411 DiagnosticsEngine &Diags) {
412 unsigned XLen = getTriple().isArch64Bit() ? 64 : 32;
413 auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, Features);
414 if (!ParseResult) {
415 std::string Buffer;
416 llvm::raw_string_ostream OutputErrMsg(Buffer);
417 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
418 OutputErrMsg << ErrMsg.getMessage();
419 });
420 Diags.Report(diag::err_invalid_feature_combination) << OutputErrMsg.str();
421 return false;
422 } else {
423 ISAInfo = std::move(*ParseResult);
424 }
425
426 if (ABI.empty())
427 ABI = ISAInfo->computeDefaultABI().str();
428
429 if (ISAInfo->hasExtension("zfh") || ISAInfo->hasExtension("zhinx"))
430 HasFastHalfType = true;
431
432 FastScalarUnalignedAccess =
433 llvm::is_contained(Features, "+unaligned-scalar-mem");
434
435 if (llvm::is_contained(Features, "+experimental"))
436 HasExperimental = true;
437
438 if (ABI == "ilp32e" && ISAInfo->hasExtension("d")) {
439 Diags.Report(diag::err_invalid_feature_combination)
440 << "ILP32E cannot be used with the D ISA extension";
441 return false;
442 }
443 return true;
444}
445
446bool RISCVTargetInfo::isValidCPUName(StringRef Name) const {
447 bool Is64Bit = getTriple().isArch64Bit();
448 return llvm::RISCV::parseCPU(Name, Is64Bit);
449}
450
452 SmallVectorImpl<StringRef> &Values) const {
453 bool Is64Bit = getTriple().isArch64Bit();
454 llvm::RISCV::fillValidCPUArchList(Values, Is64Bit);
455}
456
457bool RISCVTargetInfo::isValidTuneCPUName(StringRef Name) const {
458 bool Is64Bit = getTriple().isArch64Bit();
459 return llvm::RISCV::parseTuneCPU(Name, Is64Bit);
460}
461
463 SmallVectorImpl<StringRef> &Values) const {
464 bool Is64Bit = getTriple().isArch64Bit();
465 llvm::RISCV::fillValidTuneCPUArchList(Values, Is64Bit);
466}
467
468static void populateNegativeRISCVFeatures(std::vector<std::string> &Features) {
469 auto RII = llvm::RISCVISAInfo::parseArchString(
470 "rv64i", /* EnableExperimentalExtension */ true);
471
472 if (llvm::errorToBool(RII.takeError()))
473 llvm_unreachable("unsupport rv64i");
474
475 std::vector<std::string> FeatStrings =
476 (*RII)->toFeatures(/* AddAllExtensions */ true);
477 llvm::append_range(Features, FeatStrings);
478}
479
480static void handleFullArchString(StringRef FullArchStr,
481 std::vector<std::string> &Features) {
482 auto RII = llvm::RISCVISAInfo::parseArchString(
483 FullArchStr, /* EnableExperimentalExtension */ true);
484 if (llvm::errorToBool(RII.takeError())) {
485 // Forward the invalid FullArchStr.
486 Features.push_back(FullArchStr.str());
487 } else {
488 // Append a full list of features, including any negative extensions so that
489 // we override the CPU's features.
491 std::vector<std::string> FeatStrings =
492 (*RII)->toFeatures(/* AddAllExtensions */ true);
493 llvm::append_range(Features, FeatStrings);
494 }
495}
496
499 if (Features == "default")
500 return Ret;
501 SmallVector<StringRef, 1> AttrFeatures;
502 Features.split(AttrFeatures, ";");
503 bool FoundArch = false;
504
505 auto handleArchExtension = [](StringRef AttrString,
506 std::vector<std::string> &Features) {
508 AttrString.split(Exts, ",");
509 for (auto Ext : Exts) {
510 if (Ext.empty())
511 continue;
512
513 StringRef ExtName = Ext.substr(1);
514 std::string TargetFeature =
515 llvm::RISCVISAInfo::getTargetFeatureForExtension(ExtName);
516 if (!TargetFeature.empty())
517 Features.push_back(Ext.front() + TargetFeature);
518 else
519 Features.push_back(Ext.str());
520 }
521 };
522
523 for (auto &Feature : AttrFeatures) {
524 Feature = Feature.trim();
525 StringRef AttrString = Feature.split("=").second.trim();
526
527 if (Feature.starts_with("arch=")) {
528 // Override last features
529 Ret.Features.clear();
530 if (FoundArch)
531 Ret.Duplicate = "arch=";
532 FoundArch = true;
533
534 if (AttrString.starts_with("+")) {
535 // EXTENSION like arch=+v,+zbb
536 handleArchExtension(AttrString, Ret.Features);
537 } else {
538 // full-arch-string like arch=rv64gcv
539 handleFullArchString(AttrString, Ret.Features);
540 }
541 } else if (Feature.starts_with("cpu=")) {
542 if (!Ret.CPU.empty())
543 Ret.Duplicate = "cpu=";
544
545 Ret.CPU = AttrString;
546
547 if (!FoundArch) {
548 // Update Features with CPU's features
549 StringRef MarchFromCPU = llvm::RISCV::getMArchFromMcpu(Ret.CPU);
550 if (MarchFromCPU != "") {
551 Ret.Features.clear();
552 handleFullArchString(MarchFromCPU, Ret.Features);
553 }
554 }
555 } else if (Feature.starts_with("tune=")) {
556 if (!Ret.Tune.empty())
557 Ret.Duplicate = "tune=";
558
559 Ret.Tune = AttrString;
560 } else if (Feature.starts_with("priority")) {
561 // Skip because it only use for FMV.
562 } else if (Feature.starts_with("+")) {
563 // Handle target_version/target_clones attribute strings
564 // that are already delimited by ','
565 handleArchExtension(Feature, Ret.Features);
566 }
567 }
568 return Ret;
569}
570
571llvm::APInt
573 // Priority is explicitly specified on RISC-V unlike on other targets, where
574 // it is derived by all the features of a specific version. Therefore if a
575 // feature contains the priority string, then return it immediately.
576 for (StringRef Feature : Features) {
577 auto [LHS, RHS] = Feature.rsplit(';');
578 if (LHS.consume_front("priority="))
579 Feature = LHS;
580 else if (RHS.consume_front("priority="))
581 Feature = RHS;
582 else
583 continue;
584 unsigned Priority;
585 if (!Feature.getAsInteger(0, Priority))
586 return llvm::APInt(32, Priority);
587 }
588 // Default Priority is zero.
589 return llvm::APInt::getZero(32);
590}
591
594 switch (CC) {
595 default:
596 return CCCR_Warning;
597 case CC_C:
611 return CCCR_OK;
612 }
613}
614
616 // Only allow extensions we have a known bit position for in the
617 // __riscv_feature_bits structure.
618 return -1 != llvm::RISCVISAInfo::getRISCVFeaturesBitsInfo(Feature).second;
619}
620
621bool RISCVTargetInfo::isValidFeatureName(StringRef Name) const {
622 return llvm::RISCVISAInfo::isSupportedExtensionFeature(Name);
623}
624
626 StringRef RegName, unsigned RegSize, bool &HasSizeMismatch) const {
627 if (RegName == "ra" || RegName == "sp" || RegName == "gp" ||
628 RegName == "tp" || RegName.starts_with("x") || RegName.starts_with("a") ||
629 RegName.starts_with("s") || RegName.starts_with("t")) {
630 unsigned XLen = getTriple().isArch64Bit() ? 64 : 32;
631 HasSizeMismatch = RegSize != XLen;
632 return true;
633 }
634 return false;
635}
636
637bool RISCVTargetInfo::validateCpuIs(StringRef CPUName) const {
638 assert(getTriple().isOSLinux() &&
639 "__builtin_cpu_is() is only supported for Linux.");
640
641 return llvm::RISCV::hasValidCPUModel(CPUName);
642}
Defines the Diagnostic-related interfaces.
static constexpr llvm::StringTable BuiltinStrings
Definition AMDGPU.cpp:101
static constexpr int NumRISCVBuiltins
Definition RISCV.cpp:271
static constexpr int NumRVVAndesBuiltins
Definition RISCV.cpp:269
static constexpr int NumRVVBuiltins
Definition RISCV.cpp:265
static void populateNegativeRISCVFeatures(std::vector< std::string > &Features)
Definition RISCV.cpp:468
static constexpr int NumRVVSiFiveBuiltins
Definition RISCV.cpp:267
static unsigned getVersionValue(unsigned MajorVersion, unsigned MinorVersion)
Definition RISCV.cpp:142
static void handleFullArchString(StringRef FullArchStr, std::vector< std::string > &Features)
Definition RISCV.cpp:480
static constexpr Builtin::Info BuiltinInfos[]
Definition Builtins.cpp:38
static constexpr unsigned NumBuiltins
Definition Builtins.cpp:32
Defines the clang::MacroBuilder utility class.
Enumerates target-specific builtins in their own namespaces within namespace clang.
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:231
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
TargetOptions & getTargetOpts() const
Retrieve the target options.
Definition TargetInfo.h:323
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
virtual bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeatureVec) const
Initialize the map with the default set of target features for the CPU this should include all legal ...
virtual std::string convertConstraint(const char *&Constraint) const
bool isValidFeatureName(StringRef Name) const override
Determine whether this TargetInfo supports the given feature.
Definition RISCV.cpp:621
std::string convertConstraint(const char *&Constraint) const override
Definition RISCV.cpp:126
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
Definition RISCV.cpp:146
bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override
Definition RISCV.cpp:74
bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize, bool &HasSizeMismatch) const override
Validate register name used for global register variables.
Definition RISCV.cpp:625
bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeaturesVec) const override
Initialize the map with the default set of target features for the CPU this should include all legal ...
Definition RISCV.cpp:338
std::unique_ptr< llvm::RISCVISAInfo > ISAInfo
Definition RISCV.h:30
void fillValidTuneCPUList(SmallVectorImpl< StringRef > &Values) const override
Fill a SmallVectorImpl with the valid values for tuning CPU.
Definition RISCV.cpp:462
bool isValidTuneCPUName(StringRef Name) const override
Determine whether this TargetInfo supports the given CPU name for tuning.
Definition RISCV.cpp:457
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override
Determines whether a given calling convention is valid for the target.
Definition RISCV.cpp:593
ArrayRef< const char * > getGCCRegNames() const override
Definition RISCV.cpp:25
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
Definition RISCV.cpp:53
void fillValidCPUList(SmallVectorImpl< StringRef > &Values) const override
Fill a SmallVectorImpl with the valid values to setCPU.
Definition RISCV.cpp:451
llvm::APInt getFMVPriority(ArrayRef< StringRef > Features) const override
Definition RISCV.cpp:572
bool validateCpuSupports(StringRef Feature) const override
Definition RISCV.cpp:615
std::optional< std::pair< unsigned, unsigned > > getVScaleRange(const LangOptions &LangOpts, ArmStreamingKind Mode, llvm::StringMap< bool > *FeatureMap=nullptr) const override
Returns target-specific min and max values VScale_Range.
Definition RISCV.cpp:369
StringRef getABI() const override
Get the ABI currently in use.
Definition RISCV.h:61
CFBranchLabelSchemeKind getDefaultCFBranchLabelScheme() const override
Get the target default CFBranchLabelScheme scheme.
Definition RISCV.h:155
bool handleTargetFeatures(std::vector< std::string > &Features, DiagnosticsEngine &Diags) override
Perform initialization based on the user configured set of features.
Definition RISCV.cpp:410
llvm::SmallVector< Builtin::InfosShard > getTargetBuiltins() const override
Return information about target-specific builtins for the current primary target, and info about whic...
Definition RISCV.cpp:329
ParsedTargetAttr parseTargetAttr(StringRef Str) const override
Definition RISCV.cpp:497
bool hasFeature(StringRef Feature) const override
Return true if has this feature, need to sync with handleTargetFeatures.
Definition RISCV.cpp:393
bool validateCpuIs(StringRef CPUName) const override
Definition RISCV.cpp:637
bool isValidCPUName(StringRef Name) const override
Determine whether this TargetInfo supports the given CPU name.
Definition RISCV.cpp:446
static constexpr std::array< Builtin::Info, NumRVVAndesBuiltins > BuiltinInfos
Definition RISCV.cpp:309
static constexpr std::array< Builtin::Info, NumRVVSiFiveBuiltins > BuiltinInfos
Definition RISCV.cpp:296
Definition RISCV.cpp:278
static constexpr std::array< Builtin::Info, NumRVVBuiltins > BuiltinInfos
Definition RISCV.cpp:284
static const char *const GCCRegNames[]
Definition X86.cpp:73
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
Definition TypeBase.h:905
CallingConv
CallingConv - Specifies the calling convention that a function uses.
Definition Specifiers.h:278
@ CC_RISCVVLSCall_64
Definition Specifiers.h:303
@ CC_RISCVVLSCall_128
Definition Specifiers.h:304
@ CC_RISCVVLSCall_65536
Definition Specifiers.h:314
@ CC_RISCVVLSCall_4096
Definition Specifiers.h:310
@ CC_RISCVVLSCall_8192
Definition Specifiers.h:311
@ CC_RISCVVLSCall_512
Definition Specifiers.h:307
@ CC_RISCVVectorCall
Definition Specifiers.h:301
@ CC_RISCVVLSCall_32
Definition Specifiers.h:302
@ CC_RISCVVLSCall_16384
Definition Specifiers.h:312
@ CC_RISCVVLSCall_2048
Definition Specifiers.h:309
@ CC_RISCVVLSCall_256
Definition Specifiers.h:306
@ CC_RISCVVLSCall_1024
Definition Specifiers.h:308
@ CC_RISCVVLSCall_32768
Definition Specifiers.h:313
bool IsArmStreamingFunction(const FunctionDecl *FD, bool IncludeLocallyStreaming)
Returns whether the given FunctionDecl has an __arm[_locally]_streaming attribute.
Definition Decl.cpp:5967
The info used to represent each builtin.
Definition Builtins.h:78
Contains information gathered from parsing the contents of TargetAttr.
Definition TargetInfo.h:60
void setRequiresImmediate(int Min, int Max)