clang 19.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"
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 'v':
104 // A vector register.
105 if (Name[1] == 'r' || Name[1] == 'm') {
106 Info.setAllowsRegister();
107 Name += 1;
108 return true;
109 }
110 return false;
111 }
112}
113
114std::string RISCVTargetInfo::convertConstraint(const char *&Constraint) const {
115 std::string R;
116 switch (*Constraint) {
117 case 'v':
118 R = std::string("^") + std::string(Constraint, 2);
119 Constraint += 1;
120 break;
121 default:
122 R = TargetInfo::convertConstraint(Constraint);
123 break;
124 }
125 return R;
126}
127
128static unsigned getVersionValue(unsigned MajorVersion, unsigned MinorVersion) {
129 return MajorVersion * 1000000 + MinorVersion * 1000;
130}
131
133 MacroBuilder &Builder) const {
134 Builder.defineMacro("__riscv");
135 bool Is64Bit = getTriple().isRISCV64();
136 Builder.defineMacro("__riscv_xlen", Is64Bit ? "64" : "32");
137 StringRef CodeModel = getTargetOpts().CodeModel;
138 unsigned FLen = ISAInfo->getFLen();
139 unsigned MinVLen = ISAInfo->getMinVLen();
140 unsigned MaxELen = ISAInfo->getMaxELen();
141 unsigned MaxELenFp = ISAInfo->getMaxELenFp();
142 if (CodeModel == "default")
143 CodeModel = "small";
144
145 if (CodeModel == "small")
146 Builder.defineMacro("__riscv_cmodel_medlow");
147 else if (CodeModel == "medium")
148 Builder.defineMacro("__riscv_cmodel_medany");
149
150 StringRef ABIName = getABI();
151 if (ABIName == "ilp32f" || ABIName == "lp64f")
152 Builder.defineMacro("__riscv_float_abi_single");
153 else if (ABIName == "ilp32d" || ABIName == "lp64d")
154 Builder.defineMacro("__riscv_float_abi_double");
155 else
156 Builder.defineMacro("__riscv_float_abi_soft");
157
158 if (ABIName == "ilp32e" || ABIName == "lp64e")
159 Builder.defineMacro("__riscv_abi_rve");
160
161 Builder.defineMacro("__riscv_arch_test");
162
163 for (auto &Extension : ISAInfo->getExtensions()) {
164 auto ExtName = Extension.first;
165 auto ExtInfo = Extension.second;
166
167 Builder.defineMacro(Twine("__riscv_", ExtName),
168 Twine(getVersionValue(ExtInfo.Major, ExtInfo.Minor)));
169 }
170
171 if (ISAInfo->hasExtension("m") || ISAInfo->hasExtension("zmmul"))
172 Builder.defineMacro("__riscv_mul");
173
174 if (ISAInfo->hasExtension("m")) {
175 Builder.defineMacro("__riscv_div");
176 Builder.defineMacro("__riscv_muldiv");
177 }
178
179 if (ISAInfo->hasExtension("a")) {
180 Builder.defineMacro("__riscv_atomic");
181 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
182 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
183 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
184 if (Is64Bit)
185 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
186 }
187
188 if (FLen) {
189 Builder.defineMacro("__riscv_flen", Twine(FLen));
190 Builder.defineMacro("__riscv_fdiv");
191 Builder.defineMacro("__riscv_fsqrt");
192 }
193
194 if (MinVLen) {
195 Builder.defineMacro("__riscv_v_min_vlen", Twine(MinVLen));
196 Builder.defineMacro("__riscv_v_elen", Twine(MaxELen));
197 Builder.defineMacro("__riscv_v_elen_fp", Twine(MaxELenFp));
198 }
199
200 if (ISAInfo->hasExtension("c"))
201 Builder.defineMacro("__riscv_compressed");
202
203 if (ISAInfo->hasExtension("zve32x")) {
204 Builder.defineMacro("__riscv_vector");
205 // Currently we support the v0.12 RISC-V V intrinsics.
206 Builder.defineMacro("__riscv_v_intrinsic", Twine(getVersionValue(0, 12)));
207 }
208
209 auto VScale = getVScaleRange(Opts);
210 if (VScale && VScale->first && VScale->first == VScale->second)
211 Builder.defineMacro("__riscv_v_fixed_vlen",
212 Twine(VScale->first * llvm::RISCV::RVVBitsPerBlock));
213
214 if (FastUnalignedAccess)
215 Builder.defineMacro("__riscv_misaligned_fast");
216 else
217 Builder.defineMacro("__riscv_misaligned_avoid");
218
219 if (ISAInfo->hasExtension("e")) {
220 if (Is64Bit)
221 Builder.defineMacro("__riscv_64e");
222 else
223 Builder.defineMacro("__riscv_32e");
224 }
225}
226
227static constexpr Builtin::Info BuiltinInfo[] = {
228#define BUILTIN(ID, TYPE, ATTRS) \
229 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
230#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
231 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
232#include "clang/Basic/BuiltinsRISCVVector.def"
233#define BUILTIN(ID, TYPE, ATTRS) \
234 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
235#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
236 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
237#include "clang/Basic/BuiltinsRISCV.inc"
238};
239
243}
244
246 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
247 const std::vector<std::string> &FeaturesVec) const {
248
249 unsigned XLen = 32;
250
251 if (getTriple().isRISCV64()) {
252 Features["64bit"] = true;
253 XLen = 64;
254 } else {
255 Features["32bit"] = true;
256 }
257
258 // If a target attribute specified a full arch string, override all the ISA
259 // extension target features.
260 const auto I = llvm::find(FeaturesVec, "__RISCV_TargetAttrNeedOverride");
261 if (I != FeaturesVec.end()) {
262 std::vector<std::string> OverrideFeatures(std::next(I), FeaturesVec.end());
263
264 // Add back any non ISA extension features, e.g. +relax.
265 auto IsNonISAExtFeature = [](StringRef Feature) {
266 assert(Feature.size() > 1 && (Feature[0] == '+' || Feature[0] == '-'));
267 StringRef Ext = Feature.substr(1); // drop the +/-
268 return !llvm::RISCVISAInfo::isSupportedExtensionFeature(Ext);
269 };
270 llvm::copy_if(llvm::make_range(FeaturesVec.begin(), I),
271 std::back_inserter(OverrideFeatures), IsNonISAExtFeature);
272
273 return TargetInfo::initFeatureMap(Features, Diags, CPU, OverrideFeatures);
274 }
275
276 // Otherwise, parse the features and add any implied extensions.
277 std::vector<std::string> AllFeatures = FeaturesVec;
278 auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesVec);
279 if (!ParseResult) {
280 std::string Buffer;
281 llvm::raw_string_ostream OutputErrMsg(Buffer);
282 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
283 OutputErrMsg << ErrMsg.getMessage();
284 });
285 Diags.Report(diag::err_invalid_feature_combination) << OutputErrMsg.str();
286 return false;
287 }
288
289 // Append all features, not just new ones, so we override any negatives.
290 llvm::append_range(AllFeatures, (*ParseResult)->toFeatures());
291 return TargetInfo::initFeatureMap(Features, Diags, CPU, AllFeatures);
292}
293
294std::optional<std::pair<unsigned, unsigned>>
296 // RISCV::RVVBitsPerBlock is 64.
297 unsigned VScaleMin = ISAInfo->getMinVLen() / llvm::RISCV::RVVBitsPerBlock;
298
299 if (LangOpts.VScaleMin || LangOpts.VScaleMax) {
300 // Treat Zvl*b as a lower bound on vscale.
301 VScaleMin = std::max(VScaleMin, LangOpts.VScaleMin);
302 unsigned VScaleMax = LangOpts.VScaleMax;
303 if (VScaleMax != 0 && VScaleMax < VScaleMin)
304 VScaleMax = VScaleMin;
305 return std::pair<unsigned, unsigned>(VScaleMin ? VScaleMin : 1, VScaleMax);
306 }
307
308 if (VScaleMin > 0) {
309 unsigned VScaleMax = ISAInfo->getMaxVLen() / llvm::RISCV::RVVBitsPerBlock;
310 return std::make_pair(VScaleMin, VScaleMax);
311 }
312
313 return std::nullopt;
314}
315
316/// Return true if has this feature, need to sync with handleTargetFeatures.
317bool RISCVTargetInfo::hasFeature(StringRef Feature) const {
318 bool Is64Bit = getTriple().isRISCV64();
319 auto Result = llvm::StringSwitch<std::optional<bool>>(Feature)
320 .Case("riscv", true)
321 .Case("riscv32", !Is64Bit)
322 .Case("riscv64", Is64Bit)
323 .Case("32bit", !Is64Bit)
324 .Case("64bit", Is64Bit)
325 .Case("experimental", HasExperimental)
326 .Default(std::nullopt);
327 if (Result)
328 return *Result;
329
330 return ISAInfo->hasExtension(Feature);
331}
332
333/// Perform initialization based on the user configured set of features.
334bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
335 DiagnosticsEngine &Diags) {
336 unsigned XLen = getTriple().isArch64Bit() ? 64 : 32;
337 auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, Features);
338 if (!ParseResult) {
339 std::string Buffer;
340 llvm::raw_string_ostream OutputErrMsg(Buffer);
341 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
342 OutputErrMsg << ErrMsg.getMessage();
343 });
344 Diags.Report(diag::err_invalid_feature_combination) << OutputErrMsg.str();
345 return false;
346 } else {
347 ISAInfo = std::move(*ParseResult);
348 }
349
350 if (ABI.empty())
351 ABI = ISAInfo->computeDefaultABI().str();
352
353 if (ISAInfo->hasExtension("zfh") || ISAInfo->hasExtension("zhinx"))
354 HasLegalHalfType = true;
355
356 FastUnalignedAccess = llvm::is_contained(Features, "+fast-unaligned-access");
357
358 if (llvm::is_contained(Features, "+experimental"))
359 HasExperimental = true;
360
361 if (ABI == "ilp32e" && ISAInfo->hasExtension("d")) {
362 Diags.Report(diag::err_invalid_feature_combination)
363 << "ILP32E cannot be used with the D ISA extension";
364 return false;
365 }
366 return true;
367}
368
369bool RISCVTargetInfo::isValidCPUName(StringRef Name) const {
370 bool Is64Bit = getTriple().isArch64Bit();
371 return llvm::RISCV::parseCPU(Name, Is64Bit);
372}
373
375 SmallVectorImpl<StringRef> &Values) const {
376 bool Is64Bit = getTriple().isArch64Bit();
377 llvm::RISCV::fillValidCPUArchList(Values, Is64Bit);
378}
379
380bool RISCVTargetInfo::isValidTuneCPUName(StringRef Name) const {
381 bool Is64Bit = getTriple().isArch64Bit();
382 return llvm::RISCV::parseTuneCPU(Name, Is64Bit);
383}
384
386 SmallVectorImpl<StringRef> &Values) const {
387 bool Is64Bit = getTriple().isArch64Bit();
388 llvm::RISCV::fillValidTuneCPUArchList(Values, Is64Bit);
389}
390
391static void handleFullArchString(StringRef FullArchStr,
392 std::vector<std::string> &Features) {
393 Features.push_back("__RISCV_TargetAttrNeedOverride");
394 auto RII = llvm::RISCVISAInfo::parseArchString(
395 FullArchStr, /* EnableExperimentalExtension */ true);
396 if (llvm::errorToBool(RII.takeError())) {
397 // Forward the invalid FullArchStr.
398 Features.push_back("+" + FullArchStr.str());
399 } else {
400 // Append a full list of features, including any negative extensions so that
401 // we override the CPU's features.
402 std::vector<std::string> FeatStrings =
403 (*RII)->toFeatures(/* AddAllExtensions */ true);
404 Features.insert(Features.end(), FeatStrings.begin(), FeatStrings.end());
405 }
406}
407
410 if (Features == "default")
411 return Ret;
412 SmallVector<StringRef, 1> AttrFeatures;
413 Features.split(AttrFeatures, ";");
414 bool FoundArch = false;
415
416 for (auto &Feature : AttrFeatures) {
417 Feature = Feature.trim();
418 StringRef AttrString = Feature.split("=").second.trim();
419
420 if (Feature.starts_with("arch=")) {
421 // Override last features
422 Ret.Features.clear();
423 if (FoundArch)
424 Ret.Duplicate = "arch=";
425 FoundArch = true;
426
427 if (AttrString.starts_with("+")) {
428 // EXTENSION like arch=+v,+zbb
430 AttrString.split(Exts, ",");
431 for (auto Ext : Exts) {
432 if (Ext.empty())
433 continue;
434
435 StringRef ExtName = Ext.substr(1);
436 std::string TargetFeature =
437 llvm::RISCVISAInfo::getTargetFeatureForExtension(ExtName);
438 if (!TargetFeature.empty())
439 Ret.Features.push_back(Ext.front() + TargetFeature);
440 else
441 Ret.Features.push_back(Ext.str());
442 }
443 } else {
444 // full-arch-string like arch=rv64gcv
445 handleFullArchString(AttrString, Ret.Features);
446 }
447 } else if (Feature.starts_with("cpu=")) {
448 if (!Ret.CPU.empty())
449 Ret.Duplicate = "cpu=";
450
451 Ret.CPU = AttrString;
452
453 if (!FoundArch) {
454 // Update Features with CPU's features
455 StringRef MarchFromCPU = llvm::RISCV::getMArchFromMcpu(Ret.CPU);
456 if (MarchFromCPU != "") {
457 Ret.Features.clear();
458 handleFullArchString(MarchFromCPU, Ret.Features);
459 }
460 }
461 } else if (Feature.starts_with("tune=")) {
462 if (!Ret.Tune.empty())
463 Ret.Duplicate = "tune=";
464
465 Ret.Tune = AttrString;
466 }
467 }
468 return Ret;
469}
470
473 switch (CC) {
474 default:
475 return CCCR_Warning;
476 case CC_C:
478 return CCCR_OK;
479 }
480}
Defines the Diagnostic-related interfaces.
static unsigned getVersionValue(unsigned MajorVersion, unsigned MinorVersion)
Definition: RISCV.cpp:128
static void handleFullArchString(StringRef FullArchStr, std::vector< std::string > &Features)
Definition: RISCV.cpp:391
static constexpr Builtin::Info BuiltinInfo[]
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:192
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1547
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:449
TargetOptions & getTargetOpts() const
Retrieve the target options.
Definition: TargetInfo.h:307
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:1235
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 ...
Definition: TargetInfo.cpp:522
virtual std::string convertConstraint(const char *&Constraint) const
Definition: TargetInfo.h:1212
std::string convertConstraint(const char *&Constraint) const override
Definition: RISCV.cpp:114
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
Definition: RISCV.cpp:132
ArrayRef< Builtin::Info > getTargetBuiltins() const override
Return information about target-specific builtins for the current primary target, and info about whic...
Definition: RISCV.cpp:240
bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override
Definition: RISCV.cpp:74
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:245
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:385
bool isValidTuneCPUName(StringRef Name) const override
Determine whether this TargetInfo supports the given CPU name for tuning.
Definition: RISCV.cpp:380
std::optional< std::pair< unsigned, unsigned > > getVScaleRange(const LangOptions &LangOpts) const override
Returns target-specific min and max values VScale_Range.
Definition: RISCV.cpp:295
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override
Determines whether a given calling convention is valid for the target.
Definition: RISCV.cpp:472
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:374
StringRef getABI() const override
Get the ABI currently in use.
Definition: RISCV.h:61
bool handleTargetFeatures(std::vector< std::string > &Features, DiagnosticsEngine &Diags) override
Perform initialization based on the user configured set of features.
Definition: RISCV.cpp:334
ParsedTargetAttr parseTargetAttr(StringRef Str) const override
Definition: RISCV.cpp:408
bool hasFeature(StringRef Feature) const override
Return true if has this feature, need to sync with handleTargetFeatures.
Definition: RISCV.cpp:317
bool isValidCPUName(StringRef Name) const override
Determine whether this TargetInfo supports the given CPU name.
Definition: RISCV.cpp:369
static const char *const GCCRegNames[]
Definition: X86.cpp:44
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
Definition: Specifiers.h:275
@ CC_C
Definition: Specifiers.h:276
@ CC_RISCVVectorCall
Definition: Specifiers.h:299
Contains information gathered from parsing the contents of TargetAttr.
Definition: TargetInfo.h:56
void setRequiresImmediate(int Min, int Max)
Definition: TargetInfo.h:1132