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 // The "a" extension is composed of "zalrsc" and "zaamo"
196 if (ISAInfo->hasExtension("a"))
197 Builder.defineMacro("__riscv_atomic");
198
199 if (ISAInfo->hasExtension("zalrsc")) {
200 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
201 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
202 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
203 if (Is64Bit)
204 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
205 }
206
207 if (FLen) {
208 Builder.defineMacro("__riscv_flen", Twine(FLen));
209 Builder.defineMacro("__riscv_fdiv");
210 Builder.defineMacro("__riscv_fsqrt");
211 }
212
213 if (MinVLen) {
214 Builder.defineMacro("__riscv_v_min_vlen", Twine(MinVLen));
215 Builder.defineMacro("__riscv_v_elen", Twine(MaxELen));
216 Builder.defineMacro("__riscv_v_elen_fp", Twine(MaxELenFp));
217 }
218
219 if (ISAInfo->hasExtension("c"))
220 Builder.defineMacro("__riscv_compressed");
221
222 if (ISAInfo->hasExtension("zve32x"))
223 Builder.defineMacro("__riscv_vector");
224
225 // Currently we support the v1.0 RISC-V V intrinsics.
226 Builder.defineMacro("__riscv_v_intrinsic", Twine(getVersionValue(1, 0)));
227
229 if (VScale && VScale->first && VScale->first == VScale->second)
230 Builder.defineMacro("__riscv_v_fixed_vlen",
231 Twine(VScale->first * llvm::RISCV::RVVBitsPerBlock));
232
233 if (FastScalarUnalignedAccess)
234 Builder.defineMacro("__riscv_misaligned_fast");
235 else
236 Builder.defineMacro("__riscv_misaligned_avoid");
237
238 if (ISAInfo->hasExtension("e")) {
239 if (Is64Bit)
240 Builder.defineMacro("__riscv_64e");
241 else
242 Builder.defineMacro("__riscv_32e");
243 }
244
245 if (Opts.CFProtectionReturn && ISAInfo->hasExtension("zicfiss"))
246 Builder.defineMacro("__riscv_shadow_stack");
247
248 if (Opts.CFProtectionBranch) {
249 auto Scheme = Opts.getCFBranchLabelScheme();
252
253 Builder.defineMacro("__riscv_landing_pad");
254 switch (Scheme) {
255 case CFBranchLabelSchemeKind::Unlabeled:
256 Builder.defineMacro("__riscv_landing_pad_unlabeled");
257 break;
258 case CFBranchLabelSchemeKind::FuncSig:
259 // TODO: Define macros after the func-sig scheme is implemented
260 break;
262 llvm_unreachable("default cf-branch-label scheme should already be "
263 "transformed to other scheme");
264 }
265 }
266}
267
268static constexpr int NumRVVBuiltins =
270static constexpr int NumRVVSiFiveBuiltins =
272static constexpr int NumRVVAndesBuiltins =
274static constexpr int NumRISCVBuiltins =
276static constexpr int NumBuiltins =
280
281namespace RVV {
282#define GET_RISCVV_BUILTIN_STR_TABLE
283#include "clang/Basic/riscv_vector_builtins.inc"
284#undef GET_RISCVV_BUILTIN_STR_TABLE
285static_assert(BuiltinStrings.size() < 100'000);
286
287static constexpr std::array<Builtin::Info, NumRVVBuiltins> BuiltinInfos = {
288#define GET_RISCVV_BUILTIN_INFOS
289#include "clang/Basic/riscv_vector_builtins.inc"
290#undef GET_RISCVV_BUILTIN_INFOS
291};
292} // namespace RVV
293
294namespace RVVSiFive {
295#define GET_RISCVV_BUILTIN_STR_TABLE
296#include "clang/Basic/riscv_sifive_vector_builtins.inc"
297#undef GET_RISCVV_BUILTIN_STR_TABLE
298
299static constexpr std::array<Builtin::Info, NumRVVSiFiveBuiltins> BuiltinInfos =
300 {
301#define GET_RISCVV_BUILTIN_INFOS
302#include "clang/Basic/riscv_sifive_vector_builtins.inc"
303#undef GET_RISCVV_BUILTIN_INFOS
304};
305} // namespace RVVSiFive
306
307namespace RVVAndes {
308#define GET_RISCVV_BUILTIN_STR_TABLE
309#include "clang/Basic/riscv_andes_vector_builtins.inc"
310#undef GET_RISCVV_BUILTIN_STR_TABLE
311
312static constexpr std::array<Builtin::Info, NumRVVAndesBuiltins> BuiltinInfos =
313 {
314#define GET_RISCVV_BUILTIN_INFOS
315#include "clang/Basic/riscv_andes_vector_builtins.inc"
316#undef GET_RISCVV_BUILTIN_INFOS
317};
318} // namespace RVVAndes
319
320#define GET_BUILTIN_STR_TABLE
321#include "clang/Basic/BuiltinsRISCV.inc"
322#undef GET_BUILTIN_STR_TABLE
323
324static constexpr Builtin::Info BuiltinInfos[] = {
325#define GET_BUILTIN_INFOS
326#include "clang/Basic/BuiltinsRISCV.inc"
327#undef GET_BUILTIN_INFOS
328};
329static_assert(std::size(BuiltinInfos) == NumRISCVBuiltins);
330
331llvm::SmallVector<Builtin::InfosShard>
333 return {
334 {&RVV::BuiltinStrings, RVV::BuiltinInfos, "__builtin_rvv_"},
335 {&RVVSiFive::BuiltinStrings, RVVSiFive::BuiltinInfos, "__builtin_rvv_"},
336 {&RVVAndes::BuiltinStrings, RVVAndes::BuiltinInfos, "__builtin_rvv_"},
338 };
339}
340
342 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
343 const std::vector<std::string> &FeaturesVec) const {
344
345 unsigned XLen = 32;
346
347 if (getTriple().isRISCV64()) {
348 Features["64bit"] = true;
349 XLen = 64;
350 } else {
351 Features["32bit"] = true;
352 }
353
354 std::vector<std::string> AllFeatures = FeaturesVec;
355 auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesVec);
356 if (!ParseResult) {
357 std::string Buffer;
358 llvm::raw_string_ostream OutputErrMsg(Buffer);
359 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
360 OutputErrMsg << ErrMsg.getMessage();
361 });
362 Diags.Report(diag::err_invalid_feature_combination) << OutputErrMsg.str();
363 return false;
364 }
365
366 // Append all features, not just new ones, so we override any negatives.
367 llvm::append_range(AllFeatures, (*ParseResult)->toFeatures());
368 return TargetInfo::initFeatureMap(Features, Diags, CPU, AllFeatures);
369}
370
371std::optional<std::pair<unsigned, unsigned>>
374 llvm::StringMap<bool> *FeatureMap) const {
375 // RISCV::RVVBitsPerBlock is 64.
376 unsigned VScaleMin = ISAInfo->getMinVLen() / llvm::RISCV::RVVBitsPerBlock;
377
378 if (LangOpts.VScaleMin || LangOpts.VScaleMax) {
379 // Treat Zvl*b as a lower bound on vscale.
380 VScaleMin = std::max(VScaleMin, LangOpts.VScaleMin);
381 unsigned VScaleMax = LangOpts.VScaleMax;
382 if (VScaleMax != 0 && VScaleMax < VScaleMin)
383 VScaleMax = VScaleMin;
384 return std::pair<unsigned, unsigned>(VScaleMin ? VScaleMin : 1, VScaleMax);
385 }
386
387 if (VScaleMin > 0) {
388 unsigned VScaleMax = ISAInfo->getMaxVLen() / llvm::RISCV::RVVBitsPerBlock;
389 return std::make_pair(VScaleMin, VScaleMax);
390 }
391
392 return std::nullopt;
393}
394
395/// Return true if has this feature, need to sync with handleTargetFeatures.
397 bool Is64Bit = getTriple().isRISCV64();
398 auto Result = llvm::StringSwitch<std::optional<bool>>(Feature)
399 .Case("riscv", true)
400 .Case("riscv32", !Is64Bit)
401 .Case("riscv64", Is64Bit)
402 .Case("32bit", !Is64Bit)
403 .Case("64bit", Is64Bit)
404 .Case("experimental", HasExperimental)
405 .Default(std::nullopt);
406 if (Result)
407 return *Result;
408
409 return ISAInfo->hasExtension(Feature);
410}
411
412/// Perform initialization based on the user configured set of features.
413bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
414 DiagnosticsEngine &Diags) {
415 unsigned XLen = getTriple().isArch64Bit() ? 64 : 32;
416 auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, Features);
417 if (!ParseResult) {
418 std::string Buffer;
419 llvm::raw_string_ostream OutputErrMsg(Buffer);
420 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
421 OutputErrMsg << ErrMsg.getMessage();
422 });
423 Diags.Report(diag::err_invalid_feature_combination) << OutputErrMsg.str();
424 return false;
425 } else {
426 ISAInfo = std::move(*ParseResult);
427 }
428
429 if (ABI.empty())
430 ABI = ISAInfo->computeDefaultABI().str();
431
432 if (ISAInfo->hasExtension("zfh") || ISAInfo->hasExtension("zhinx"))
433 HasFastHalfType = true;
434
435 FastScalarUnalignedAccess =
436 llvm::is_contained(Features, "+unaligned-scalar-mem");
437
438 if (llvm::is_contained(Features, "+experimental"))
439 HasExperimental = true;
440
441 if (ABI == "ilp32e" && ISAInfo->hasExtension("d")) {
442 Diags.Report(diag::err_invalid_feature_combination)
443 << "ILP32E cannot be used with the D ISA extension";
444 return false;
445 }
446 return true;
447}
448
449bool RISCVTargetInfo::isValidCPUName(StringRef Name) const {
450 bool Is64Bit = getTriple().isArch64Bit();
451 return llvm::RISCV::parseCPU(Name, Is64Bit);
452}
453
455 SmallVectorImpl<StringRef> &Values) const {
456 bool Is64Bit = getTriple().isArch64Bit();
457 llvm::RISCV::fillValidCPUArchList(Values, Is64Bit);
458}
459
460bool RISCVTargetInfo::isValidTuneCPUName(StringRef Name) const {
461 bool Is64Bit = getTriple().isArch64Bit();
462 return llvm::RISCV::parseTuneCPU(Name, Is64Bit);
463}
464
466 SmallVectorImpl<StringRef> &Values) const {
467 bool Is64Bit = getTriple().isArch64Bit();
468 llvm::RISCV::fillValidTuneCPUArchList(Values, Is64Bit);
469}
470
471static void populateNegativeRISCVFeatures(std::vector<std::string> &Features) {
472 auto RII = llvm::RISCVISAInfo::parseArchString(
473 "rv64i", /* EnableExperimentalExtension */ true);
474
475 if (llvm::errorToBool(RII.takeError()))
476 llvm_unreachable("unsupport rv64i");
477
478 std::vector<std::string> FeatStrings =
479 (*RII)->toFeatures(/* AddAllExtensions */ true);
480 llvm::append_range(Features, FeatStrings);
481}
482
483static void handleFullArchString(StringRef FullArchStr,
484 std::vector<std::string> &Features) {
485 auto RII = llvm::RISCVISAInfo::parseArchString(
486 FullArchStr, /* EnableExperimentalExtension */ true);
487 if (llvm::errorToBool(RII.takeError())) {
488 // Forward the invalid FullArchStr.
489 Features.push_back(FullArchStr.str());
490 } else {
491 // Append a full list of features, including any negative extensions so that
492 // we override the CPU's features.
494 std::vector<std::string> FeatStrings =
495 (*RII)->toFeatures(/* AddAllExtensions */ true);
496 llvm::append_range(Features, FeatStrings);
497 }
498}
499
502 if (Features == "default")
503 return Ret;
504 SmallVector<StringRef, 1> AttrFeatures;
505 Features.split(AttrFeatures, ";");
506 bool FoundArch = false;
507
508 auto handleArchExtension = [](StringRef AttrString,
509 std::vector<std::string> &Features) {
511 AttrString.split(Exts, ",");
512 for (auto Ext : Exts) {
513 if (Ext.empty())
514 continue;
515
516 StringRef ExtName = Ext.substr(1);
517 std::string TargetFeature =
518 llvm::RISCVISAInfo::getTargetFeatureForExtension(ExtName);
519 if (!TargetFeature.empty())
520 Features.push_back(Ext.front() + TargetFeature);
521 else
522 Features.push_back(Ext.str());
523 }
524 };
525
526 for (auto &Feature : AttrFeatures) {
527 Feature = Feature.trim();
528 StringRef AttrString = Feature.split("=").second.trim();
529
530 if (Feature.starts_with("arch=")) {
531 // Override last features
532 Ret.Features.clear();
533 if (FoundArch)
534 Ret.Duplicate = "arch=";
535 FoundArch = true;
536
537 if (AttrString.starts_with("+")) {
538 // EXTENSION like arch=+v,+zbb
539 handleArchExtension(AttrString, Ret.Features);
540 } else {
541 // full-arch-string like arch=rv64gcv
542 handleFullArchString(AttrString, Ret.Features);
543 }
544 } else if (Feature.starts_with("cpu=")) {
545 if (!Ret.CPU.empty())
546 Ret.Duplicate = "cpu=";
547
548 Ret.CPU = AttrString;
549
550 if (!FoundArch) {
551 // Update Features with CPU's features
552 StringRef MarchFromCPU = llvm::RISCV::getMArchFromMcpu(Ret.CPU);
553 if (MarchFromCPU != "") {
554 Ret.Features.clear();
555 handleFullArchString(MarchFromCPU, Ret.Features);
556 }
557 }
558 } else if (Feature.starts_with("tune=")) {
559 if (!Ret.Tune.empty())
560 Ret.Duplicate = "tune=";
561
562 Ret.Tune = AttrString;
563 } else if (Feature.starts_with("priority")) {
564 // Skip because it only use for FMV.
565 } else if (Feature.starts_with("+")) {
566 // Handle target_version/target_clones attribute strings
567 // that are already delimited by ','
568 handleArchExtension(Feature, Ret.Features);
569 }
570 }
571 return Ret;
572}
573
574llvm::APInt
576 // Priority is explicitly specified on RISC-V unlike on other targets, where
577 // it is derived by all the features of a specific version. Therefore if a
578 // feature contains the priority string, then return it immediately.
579 for (StringRef Feature : Features) {
580 auto [LHS, RHS] = Feature.rsplit(';');
581 if (LHS.consume_front("priority="))
582 Feature = LHS;
583 else if (RHS.consume_front("priority="))
584 Feature = RHS;
585 else
586 continue;
587 unsigned Priority;
588 if (!Feature.getAsInteger(0, Priority))
589 return llvm::APInt(32, Priority);
590 }
591 // Default Priority is zero.
592 return llvm::APInt::getZero(32);
593}
594
597 switch (CC) {
598 default:
599 return CCCR_Warning;
600 case CC_C:
614 return CCCR_OK;
615 }
616}
617
619 // Only allow extensions we have a known bit position for in the
620 // __riscv_feature_bits structure.
621 return -1 != llvm::RISCVISAInfo::getRISCVFeaturesBitsInfo(Feature).second;
622}
623
624bool RISCVTargetInfo::isValidFeatureName(StringRef Name) const {
625 return llvm::RISCVISAInfo::isSupportedExtensionFeature(Name);
626}
627
629 StringRef RegName, unsigned RegSize, bool &HasSizeMismatch) const {
630 if (RegName == "ra" || RegName == "sp" || RegName == "gp" ||
631 RegName == "tp" || RegName.starts_with("x") || RegName.starts_with("a") ||
632 RegName.starts_with("s") || RegName.starts_with("t")) {
633 unsigned XLen = getTriple().isArch64Bit() ? 64 : 32;
634 HasSizeMismatch = RegSize != XLen;
635 return true;
636 }
637 return false;
638}
639
640bool RISCVTargetInfo::validateCpuIs(StringRef CPUName) const {
641 assert(getTriple().isOSLinux() &&
642 "__builtin_cpu_is() is only supported for Linux.");
643
644 return llvm::RISCV::hasValidCPUModel(CPUName);
645}
Defines the Diagnostic-related interfaces.
static constexpr llvm::StringTable BuiltinStrings
Definition AMDGPU.cpp:101
static constexpr int NumRISCVBuiltins
Definition RISCV.cpp:274
static constexpr int NumRVVAndesBuiltins
Definition RISCV.cpp:272
static constexpr int NumRVVBuiltins
Definition RISCV.cpp:268
static void populateNegativeRISCVFeatures(std::vector< std::string > &Features)
Definition RISCV.cpp:471
static constexpr int NumRVVSiFiveBuiltins
Definition RISCV.cpp:270
static unsigned getVersionValue(unsigned MajorVersion, unsigned MinorVersion)
Definition RISCV.cpp:142
static void handleFullArchString(StringRef FullArchStr, std::vector< std::string > &Features)
Definition RISCV.cpp:483
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:232
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:624
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:628
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:341
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:465
bool isValidTuneCPUName(StringRef Name) const override
Determine whether this TargetInfo supports the given CPU name for tuning.
Definition RISCV.cpp:460
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override
Determines whether a given calling convention is valid for the target.
Definition RISCV.cpp:596
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:454
llvm::APInt getFMVPriority(ArrayRef< StringRef > Features) const override
Definition RISCV.cpp:575
bool validateCpuSupports(StringRef Feature) const override
Definition RISCV.cpp:618
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:372
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:413
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:332
ParsedTargetAttr parseTargetAttr(StringRef Str) const override
Definition RISCV.cpp:500
bool hasFeature(StringRef Feature) const override
Return true if has this feature, need to sync with handleTargetFeatures.
Definition RISCV.cpp:396
bool validateCpuIs(StringRef CPUName) const override
Definition RISCV.cpp:640
bool isValidCPUName(StringRef Name) const override
Determine whether this TargetInfo supports the given CPU name.
Definition RISCV.cpp:449
static constexpr std::array< Builtin::Info, NumRVVAndesBuiltins > BuiltinInfos
Definition RISCV.cpp:312
static constexpr std::array< Builtin::Info, NumRVVSiFiveBuiltins > BuiltinInfos
Definition RISCV.cpp:299
Definition RISCV.cpp:281
static constexpr std::array< Builtin::Info, NumRVVBuiltins > BuiltinInfos
Definition RISCV.cpp:287
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:6019
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)