xref: /llvm-project/clang/lib/Basic/Targets/LoongArch.cpp (revision 19834b4623fd1e7ae5185ed76031b407c3fa7a47)
115b65bcdSWeining Lu //===--- LoongArch.cpp - Implement LoongArch target feature support -------===//
215b65bcdSWeining Lu //
315b65bcdSWeining Lu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
415b65bcdSWeining Lu // See https://llvm.org/LICENSE.txt for license information.
515b65bcdSWeining Lu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
615b65bcdSWeining Lu //
715b65bcdSWeining Lu //===----------------------------------------------------------------------===//
815b65bcdSWeining Lu //
915b65bcdSWeining Lu // This file implements LoongArch TargetInfo objects.
1015b65bcdSWeining Lu //
1115b65bcdSWeining Lu //===----------------------------------------------------------------------===//
1215b65bcdSWeining Lu 
1315b65bcdSWeining Lu #include "LoongArch.h"
1415b65bcdSWeining Lu #include "clang/Basic/Diagnostic.h"
1515b65bcdSWeining Lu #include "clang/Basic/MacroBuilder.h"
1615b65bcdSWeining Lu #include "clang/Basic/TargetBuiltins.h"
1715b65bcdSWeining Lu #include "llvm/Support/raw_ostream.h"
18f62c9252SWeining Lu #include "llvm/TargetParser/LoongArchTargetParser.h"
1915b65bcdSWeining Lu 
2015b65bcdSWeining Lu using namespace clang;
2115b65bcdSWeining Lu using namespace clang::targets;
2215b65bcdSWeining Lu 
2315b65bcdSWeining Lu ArrayRef<const char *> LoongArchTargetInfo::getGCCRegNames() const {
24394f3091SWeining Lu   static const char *const GCCRegNames[] = {
25394f3091SWeining Lu       // General purpose registers.
26394f3091SWeining Lu       "$r0", "$r1", "$r2", "$r3", "$r4", "$r5", "$r6", "$r7", "$r8", "$r9",
27394f3091SWeining Lu       "$r10", "$r11", "$r12", "$r13", "$r14", "$r15", "$r16", "$r17", "$r18",
28394f3091SWeining Lu       "$r19", "$r20", "$r21", "$r22", "$r23", "$r24", "$r25", "$r26", "$r27",
29394f3091SWeining Lu       "$r28", "$r29", "$r30", "$r31",
30394f3091SWeining Lu       // Floating point registers.
31394f3091SWeining Lu       "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", "$f8", "$f9",
32394f3091SWeining Lu       "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", "$f16", "$f17", "$f18",
33394f3091SWeining Lu       "$f19", "$f20", "$f21", "$f22", "$f23", "$f24", "$f25", "$f26", "$f27",
34161716a7SWeining Lu       "$f28", "$f29", "$f30", "$f31",
35161716a7SWeining Lu       // Condition flag registers.
36d25c79dcSchenli       "$fcc0", "$fcc1", "$fcc2", "$fcc3", "$fcc4", "$fcc5", "$fcc6", "$fcc7",
37d25c79dcSchenli       // 128-bit vector registers.
38d25c79dcSchenli       "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6", "$vr7", "$vr8",
39d25c79dcSchenli       "$vr9", "$vr10", "$vr11", "$vr12", "$vr13", "$vr14", "$vr15", "$vr16",
40d25c79dcSchenli       "$vr17", "$vr18", "$vr19", "$vr20", "$vr21", "$vr22", "$vr23", "$vr24",
41d25c79dcSchenli       "$vr25", "$vr26", "$vr27", "$vr28", "$vr29", "$vr30", "$vr31",
42d25c79dcSchenli       // 256-bit vector registers.
43d25c79dcSchenli       "$xr0", "$xr1", "$xr2", "$xr3", "$xr4", "$xr5", "$xr6", "$xr7", "$xr8",
44d25c79dcSchenli       "$xr9", "$xr10", "$xr11", "$xr12", "$xr13", "$xr14", "$xr15", "$xr16",
45d25c79dcSchenli       "$xr17", "$xr18", "$xr19", "$xr20", "$xr21", "$xr22", "$xr23", "$xr24",
46d25c79dcSchenli       "$xr25", "$xr26", "$xr27", "$xr28", "$xr29", "$xr30", "$xr31"};
47a3c248dbSserge-sans-paille   return llvm::ArrayRef(GCCRegNames);
4815b65bcdSWeining Lu }
4915b65bcdSWeining Lu 
5015b65bcdSWeining Lu ArrayRef<TargetInfo::GCCRegAlias>
5115b65bcdSWeining Lu LoongArchTargetInfo::getGCCRegAliases() const {
52394f3091SWeining Lu   static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
530bbf3ddfSWeining Lu       {{"zero", "$zero", "r0"}, "$r0"},
540bbf3ddfSWeining Lu       {{"ra", "$ra", "r1"}, "$r1"},
550bbf3ddfSWeining Lu       {{"tp", "$tp", "r2"}, "$r2"},
560bbf3ddfSWeining Lu       {{"sp", "$sp", "r3"}, "$r3"},
570bbf3ddfSWeining Lu       {{"a0", "$a0", "r4"}, "$r4"},
580bbf3ddfSWeining Lu       {{"a1", "$a1", "r5"}, "$r5"},
590bbf3ddfSWeining Lu       {{"a2", "$a2", "r6"}, "$r6"},
600bbf3ddfSWeining Lu       {{"a3", "$a3", "r7"}, "$r7"},
610bbf3ddfSWeining Lu       {{"a4", "$a4", "r8"}, "$r8"},
620bbf3ddfSWeining Lu       {{"a5", "$a5", "r9"}, "$r9"},
630bbf3ddfSWeining Lu       {{"a6", "$a6", "r10"}, "$r10"},
640bbf3ddfSWeining Lu       {{"a7", "$a7", "r11"}, "$r11"},
650bbf3ddfSWeining Lu       {{"t0", "$t0", "r12"}, "$r12"},
660bbf3ddfSWeining Lu       {{"t1", "$t1", "r13"}, "$r13"},
670bbf3ddfSWeining Lu       {{"t2", "$t2", "r14"}, "$r14"},
680bbf3ddfSWeining Lu       {{"t3", "$t3", "r15"}, "$r15"},
690bbf3ddfSWeining Lu       {{"t4", "$t4", "r16"}, "$r16"},
700bbf3ddfSWeining Lu       {{"t5", "$t5", "r17"}, "$r17"},
710bbf3ddfSWeining Lu       {{"t6", "$t6", "r18"}, "$r18"},
720bbf3ddfSWeining Lu       {{"t7", "$t7", "r19"}, "$r19"},
730bbf3ddfSWeining Lu       {{"t8", "$t8", "r20"}, "$r20"},
740bbf3ddfSWeining Lu       {{"r21"}, "$r21"},
750bbf3ddfSWeining Lu       {{"s9", "$s9", "r22", "fp", "$fp"}, "$r22"},
760bbf3ddfSWeining Lu       {{"s0", "$s0", "r23"}, "$r23"},
770bbf3ddfSWeining Lu       {{"s1", "$s1", "r24"}, "$r24"},
780bbf3ddfSWeining Lu       {{"s2", "$s2", "r25"}, "$r25"},
790bbf3ddfSWeining Lu       {{"s3", "$s3", "r26"}, "$r26"},
800bbf3ddfSWeining Lu       {{"s4", "$s4", "r27"}, "$r27"},
810bbf3ddfSWeining Lu       {{"s5", "$s5", "r28"}, "$r28"},
820bbf3ddfSWeining Lu       {{"s6", "$s6", "r29"}, "$r29"},
830bbf3ddfSWeining Lu       {{"s7", "$s7", "r30"}, "$r30"},
840bbf3ddfSWeining Lu       {{"s8", "$s8", "r31"}, "$r31"},
850bbf3ddfSWeining Lu       {{"$fa0"}, "$f0"},
860bbf3ddfSWeining Lu       {{"$fa1"}, "$f1"},
870bbf3ddfSWeining Lu       {{"$fa2"}, "$f2"},
880bbf3ddfSWeining Lu       {{"$fa3"}, "$f3"},
890bbf3ddfSWeining Lu       {{"$fa4"}, "$f4"},
900bbf3ddfSWeining Lu       {{"$fa5"}, "$f5"},
910bbf3ddfSWeining Lu       {{"$fa6"}, "$f6"},
920bbf3ddfSWeining Lu       {{"$fa7"}, "$f7"},
930bbf3ddfSWeining Lu       {{"$ft0"}, "$f8"},
940bbf3ddfSWeining Lu       {{"$ft1"}, "$f9"},
950bbf3ddfSWeining Lu       {{"$ft2"}, "$f10"},
960bbf3ddfSWeining Lu       {{"$ft3"}, "$f11"},
970bbf3ddfSWeining Lu       {{"$ft4"}, "$f12"},
980bbf3ddfSWeining Lu       {{"$ft5"}, "$f13"},
990bbf3ddfSWeining Lu       {{"$ft6"}, "$f14"},
1000bbf3ddfSWeining Lu       {{"$ft7"}, "$f15"},
1010bbf3ddfSWeining Lu       {{"$ft8"}, "$f16"},
1020bbf3ddfSWeining Lu       {{"$ft9"}, "$f17"},
1030bbf3ddfSWeining Lu       {{"$ft10"}, "$f18"},
1040bbf3ddfSWeining Lu       {{"$ft11"}, "$f19"},
1050bbf3ddfSWeining Lu       {{"$ft12"}, "$f20"},
1060bbf3ddfSWeining Lu       {{"$ft13"}, "$f21"},
1070bbf3ddfSWeining Lu       {{"$ft14"}, "$f22"},
1080bbf3ddfSWeining Lu       {{"$ft15"}, "$f23"},
1090bbf3ddfSWeining Lu       {{"$fs0"}, "$f24"},
1100bbf3ddfSWeining Lu       {{"$fs1"}, "$f25"},
1110bbf3ddfSWeining Lu       {{"$fs2"}, "$f26"},
1120bbf3ddfSWeining Lu       {{"$fs3"}, "$f27"},
1130bbf3ddfSWeining Lu       {{"$fs4"}, "$f28"},
1140bbf3ddfSWeining Lu       {{"$fs5"}, "$f29"},
1150bbf3ddfSWeining Lu       {{"$fs6"}, "$f30"},
1160bbf3ddfSWeining Lu       {{"$fs7"}, "$f31"},
117394f3091SWeining Lu   };
118a3c248dbSserge-sans-paille   return llvm::ArrayRef(GCCRegAliases);
11915b65bcdSWeining Lu }
12015b65bcdSWeining Lu 
12115b65bcdSWeining Lu bool LoongArchTargetInfo::validateAsmConstraint(
12215b65bcdSWeining Lu     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
123394f3091SWeining Lu   // See the GCC definitions here:
124394f3091SWeining Lu   // https://gcc.gnu.org/onlinedocs/gccint/Machine-Constraints.html
12542b70793SWeining Lu   // Note that the 'm' constraint is handled in TargetInfo.
126394f3091SWeining Lu   switch (*Name) {
127394f3091SWeining Lu   default:
12815b65bcdSWeining Lu     return false;
129394f3091SWeining Lu   case 'f':
130394f3091SWeining Lu     // A floating-point register (if available).
131394f3091SWeining Lu     Info.setAllowsRegister();
132394f3091SWeining Lu     return true;
13342b70793SWeining Lu   case 'k':
13442b70793SWeining Lu     // A memory operand whose address is formed by a base register and
13542b70793SWeining Lu     // (optionally scaled) index register.
13642b70793SWeining Lu     Info.setAllowsMemory();
13742b70793SWeining Lu     return true;
138394f3091SWeining Lu   case 'l':
139394f3091SWeining Lu     // A signed 16-bit constant.
140394f3091SWeining Lu     Info.setRequiresImmediate(-32768, 32767);
141394f3091SWeining Lu     return true;
142394f3091SWeining Lu   case 'I':
143394f3091SWeining Lu     // A signed 12-bit constant (for arithmetic instructions).
144394f3091SWeining Lu     Info.setRequiresImmediate(-2048, 2047);
145394f3091SWeining Lu     return true;
146cd0174aaSWeining Lu   case 'J':
147cd0174aaSWeining Lu     // Integer zero.
148cd0174aaSWeining Lu     Info.setRequiresImmediate(0);
149cd0174aaSWeining Lu     return true;
150394f3091SWeining Lu   case 'K':
151394f3091SWeining Lu     // An unsigned 12-bit constant (for logic instructions).
152394f3091SWeining Lu     Info.setRequiresImmediate(0, 4095);
153394f3091SWeining Lu     return true;
15442b70793SWeining Lu   case 'Z':
15542b70793SWeining Lu     // ZB: An address that is held in a general-purpose register. The offset is
15642b70793SWeining Lu     //     zero.
15742b70793SWeining Lu     // ZC: A memory operand whose address is formed by a base register
15842b70793SWeining Lu     //     and offset that is suitable for use in instructions with the same
15942b70793SWeining Lu     //     addressing mode as ll.w and sc.w.
16042b70793SWeining Lu     if (Name[1] == 'C' || Name[1] == 'B') {
16142b70793SWeining Lu       Info.setAllowsMemory();
16242b70793SWeining Lu       ++Name; // Skip over 'Z'.
16342b70793SWeining Lu       return true;
164394f3091SWeining Lu     }
16542b70793SWeining Lu     return false;
16642b70793SWeining Lu   }
16742b70793SWeining Lu }
16842b70793SWeining Lu 
16942b70793SWeining Lu std::string
17042b70793SWeining Lu LoongArchTargetInfo::convertConstraint(const char *&Constraint) const {
17142b70793SWeining Lu   std::string R;
17242b70793SWeining Lu   switch (*Constraint) {
17342b70793SWeining Lu   case 'Z':
17442b70793SWeining Lu     // "ZC"/"ZB" are two-character constraints; add "^" hint for later
17542b70793SWeining Lu     // parsing.
17642b70793SWeining Lu     R = "^" + std::string(Constraint, 2);
17742b70793SWeining Lu     ++Constraint;
17842b70793SWeining Lu     break;
17942b70793SWeining Lu   default:
18042b70793SWeining Lu     R = TargetInfo::convertConstraint(Constraint);
18142b70793SWeining Lu     break;
18242b70793SWeining Lu   }
18342b70793SWeining Lu   return R;
18415b65bcdSWeining Lu }
18515b65bcdSWeining Lu 
18615b65bcdSWeining Lu void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts,
18715b65bcdSWeining Lu                                            MacroBuilder &Builder) const {
18815b65bcdSWeining Lu   Builder.defineMacro("__loongarch__");
18960e5cfe2SWeining Lu   unsigned GRLen = getRegisterWidth();
19060e5cfe2SWeining Lu   Builder.defineMacro("__loongarch_grlen", Twine(GRLen));
19160e5cfe2SWeining Lu   if (GRLen == 64)
19260e5cfe2SWeining Lu     Builder.defineMacro("__loongarch64");
19360e5cfe2SWeining Lu 
19460e5cfe2SWeining Lu   if (HasFeatureD)
19560e5cfe2SWeining Lu     Builder.defineMacro("__loongarch_frlen", "64");
19660e5cfe2SWeining Lu   else if (HasFeatureF)
19760e5cfe2SWeining Lu     Builder.defineMacro("__loongarch_frlen", "32");
19860e5cfe2SWeining Lu   else
19960e5cfe2SWeining Lu     Builder.defineMacro("__loongarch_frlen", "0");
20060e5cfe2SWeining Lu 
201f62c9252SWeining Lu   // Define __loongarch_arch.
202f62c9252SWeining Lu   StringRef ArchName = getCPU();
2035a1b9896SAmi-zhang   if (ArchName == "loongarch64") {
2045a1b9896SAmi-zhang     if (HasFeatureLSX) {
2055a1b9896SAmi-zhang       // TODO: As more features of the V1.1 ISA are supported, a unified "v1.1"
2065a1b9896SAmi-zhang       // arch feature set will be used to include all sub-features belonging to
2075a1b9896SAmi-zhang       // the V1.1 ISA version.
208427be076Stangaac       if (HasFeatureFrecipe && HasFeatureLAM_BH && HasFeatureLAMCAS &&
209*19834b46Stangaac           HasFeatureLD_SEQ_SA && HasFeatureDiv32 && HasFeatureSCQ)
2105a1b9896SAmi-zhang         Builder.defineMacro("__loongarch_arch",
2115a1b9896SAmi-zhang                             Twine('"') + "la64v1.1" + Twine('"'));
2125a1b9896SAmi-zhang       else
2135a1b9896SAmi-zhang         Builder.defineMacro("__loongarch_arch",
2145a1b9896SAmi-zhang                             Twine('"') + "la64v1.0" + Twine('"'));
2155a1b9896SAmi-zhang     } else {
2165a1b9896SAmi-zhang       Builder.defineMacro("__loongarch_arch",
2175a1b9896SAmi-zhang                           Twine('"') + ArchName + Twine('"'));
2185a1b9896SAmi-zhang     }
2195a1b9896SAmi-zhang   } else {
220f62c9252SWeining Lu     Builder.defineMacro("__loongarch_arch", Twine('"') + ArchName + Twine('"'));
2215a1b9896SAmi-zhang   }
222f62c9252SWeining Lu 
223f62c9252SWeining Lu   // Define __loongarch_tune.
224f62c9252SWeining Lu   StringRef TuneCPU = getTargetOpts().TuneCPU;
225f62c9252SWeining Lu   if (TuneCPU.empty())
226f62c9252SWeining Lu     TuneCPU = ArchName;
227f62c9252SWeining Lu   Builder.defineMacro("__loongarch_tune", Twine('"') + TuneCPU + Twine('"'));
22860e5cfe2SWeining Lu 
229626c7ce3SZhaoxin Yang   if (HasFeatureLASX) {
230626c7ce3SZhaoxin Yang     Builder.defineMacro("__loongarch_simd_width", "256");
2318d4e3560Slicongtian     Builder.defineMacro("__loongarch_sx", Twine(1));
2328d4e3560Slicongtian     Builder.defineMacro("__loongarch_asx", Twine(1));
233626c7ce3SZhaoxin Yang   } else if (HasFeatureLSX) {
234626c7ce3SZhaoxin Yang     Builder.defineMacro("__loongarch_simd_width", "128");
235626c7ce3SZhaoxin Yang     Builder.defineMacro("__loongarch_sx", Twine(1));
236626c7ce3SZhaoxin Yang   }
2375a1b9896SAmi-zhang   if (HasFeatureFrecipe)
2385a1b9896SAmi-zhang     Builder.defineMacro("__loongarch_frecipe", Twine(1));
2398d4e3560Slicongtian 
2405b9c76b6Stangaac   if (HasFeatureLAM_BH)
2415b9c76b6Stangaac     Builder.defineMacro("__loongarch_lam_bh", Twine(1));
2425b9c76b6Stangaac 
243427be076Stangaac   if (HasFeatureLAMCAS)
244427be076Stangaac     Builder.defineMacro("__loongarch_lamcas", Twine(1));
245427be076Stangaac 
2461d460207Stangaac   if (HasFeatureLD_SEQ_SA)
2471d460207Stangaac     Builder.defineMacro("__loongarch_ld_seq_sa", Twine(1));
2481d460207Stangaac 
249f4379db4Stangaac   if (HasFeatureDiv32)
250f4379db4Stangaac     Builder.defineMacro("__loongarch_div32", Twine(1));
251f4379db4Stangaac 
252*19834b46Stangaac   if (HasFeatureSCQ)
253*19834b46Stangaac     Builder.defineMacro("__loongarch_scq", Twine(1));
254*19834b46Stangaac 
25560e5cfe2SWeining Lu   StringRef ABI = getABI();
25660e5cfe2SWeining Lu   if (ABI == "lp64d" || ABI == "lp64f" || ABI == "lp64s")
25760e5cfe2SWeining Lu     Builder.defineMacro("__loongarch_lp64");
25860e5cfe2SWeining Lu 
25960e5cfe2SWeining Lu   if (ABI == "lp64d" || ABI == "ilp32d") {
26060e5cfe2SWeining Lu     Builder.defineMacro("__loongarch_hard_float");
26160e5cfe2SWeining Lu     Builder.defineMacro("__loongarch_double_float");
26260e5cfe2SWeining Lu   } else if (ABI == "lp64f" || ABI == "ilp32f") {
26360e5cfe2SWeining Lu     Builder.defineMacro("__loongarch_hard_float");
26460e5cfe2SWeining Lu     Builder.defineMacro("__loongarch_single_float");
26560e5cfe2SWeining Lu   } else if (ABI == "lp64s" || ABI == "ilp32s") {
26660e5cfe2SWeining Lu     Builder.defineMacro("__loongarch_soft_float");
26760e5cfe2SWeining Lu   }
268f70d17fcSBrad Smith 
269f70d17fcSBrad Smith   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
270f70d17fcSBrad Smith   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
271f70d17fcSBrad Smith   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
272f70d17fcSBrad Smith   if (GRLen == 64)
273f70d17fcSBrad Smith     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
27415b65bcdSWeining Lu }
27515b65bcdSWeining Lu 
276ca79ff07SChandler Carruth static constexpr Builtin::Info BuiltinInfo[] = {
277ca79ff07SChandler Carruth #define BUILTIN(ID, TYPE, ATTRS)                                               \
278ca79ff07SChandler Carruth   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
279ca79ff07SChandler Carruth #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
280ca79ff07SChandler Carruth   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
28185f08c41Sgonglingqin #include "clang/Basic/BuiltinsLoongArch.def"
282ca79ff07SChandler Carruth };
28385f08c41Sgonglingqin 
284da34aff9Sgonglingqin bool LoongArchTargetInfo::initFeatureMap(
285da34aff9Sgonglingqin     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
286da34aff9Sgonglingqin     const std::vector<std::string> &FeaturesVec) const {
287da34aff9Sgonglingqin   if (getTriple().getArch() == llvm::Triple::loongarch64)
288da34aff9Sgonglingqin     Features["64bit"] = true;
2899e06d18cSXiaodong Liu   if (getTriple().getArch() == llvm::Triple::loongarch32)
2909e06d18cSXiaodong Liu     Features["32bit"] = true;
291da34aff9Sgonglingqin 
292da34aff9Sgonglingqin   return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
293da34aff9Sgonglingqin }
294da34aff9Sgonglingqin 
295da34aff9Sgonglingqin /// Return true if has this feature.
296da34aff9Sgonglingqin bool LoongArchTargetInfo::hasFeature(StringRef Feature) const {
297da34aff9Sgonglingqin   bool Is64Bit = getTriple().getArch() == llvm::Triple::loongarch64;
298da34aff9Sgonglingqin   // TODO: Handle more features.
299da34aff9Sgonglingqin   return llvm::StringSwitch<bool>(Feature)
300da34aff9Sgonglingqin       .Case("loongarch32", !Is64Bit)
301da34aff9Sgonglingqin       .Case("loongarch64", Is64Bit)
302da34aff9Sgonglingqin       .Case("32bit", !Is64Bit)
303da34aff9Sgonglingqin       .Case("64bit", Is64Bit)
3048d4e3560Slicongtian       .Case("lsx", HasFeatureLSX)
3058d4e3560Slicongtian       .Case("lasx", HasFeatureLASX)
306da34aff9Sgonglingqin       .Default(false);
307da34aff9Sgonglingqin }
308da34aff9Sgonglingqin 
309ca79ff07SChandler Carruth ArrayRef<Builtin::Info> LoongArchTargetInfo::getTargetBuiltins() const {
310ca79ff07SChandler Carruth   return llvm::ArrayRef(BuiltinInfo, clang::LoongArch::LastTSBuiltin -
311ca79ff07SChandler Carruth                                          Builtin::FirstTSBuiltin);
31215b65bcdSWeining Lu }
31360e5cfe2SWeining Lu 
31460e5cfe2SWeining Lu bool LoongArchTargetInfo::handleTargetFeatures(
31560e5cfe2SWeining Lu     std::vector<std::string> &Features, DiagnosticsEngine &Diags) {
31660e5cfe2SWeining Lu   for (const auto &Feature : Features) {
31760e5cfe2SWeining Lu     if (Feature == "+d" || Feature == "+f") {
31860e5cfe2SWeining Lu       // "d" implies "f".
31960e5cfe2SWeining Lu       HasFeatureF = true;
32060e5cfe2SWeining Lu       if (Feature == "+d") {
32160e5cfe2SWeining Lu         HasFeatureD = true;
32260e5cfe2SWeining Lu       }
3238d4e3560Slicongtian     } else if (Feature == "+lsx")
3248d4e3560Slicongtian       HasFeatureLSX = true;
3258d4e3560Slicongtian     else if (Feature == "+lasx")
3268d4e3560Slicongtian       HasFeatureLASX = true;
3277df79abaSNathan Sidwell     else if (Feature == "-ual")
3287df79abaSNathan Sidwell       HasUnalignedAccess = false;
3295a1b9896SAmi-zhang     else if (Feature == "+frecipe")
3305a1b9896SAmi-zhang       HasFeatureFrecipe = true;
3315b9c76b6Stangaac     else if (Feature == "+lam-bh")
3325b9c76b6Stangaac       HasFeatureLAM_BH = true;
333427be076Stangaac     else if (Feature == "+lamcas")
334427be076Stangaac       HasFeatureLAMCAS = true;
3351d460207Stangaac     else if (Feature == "+ld-seq-sa")
3361d460207Stangaac       HasFeatureLD_SEQ_SA = true;
337f4379db4Stangaac     else if (Feature == "+div32")
338f4379db4Stangaac       HasFeatureDiv32 = true;
339*19834b46Stangaac     else if (Feature == "+scq")
340*19834b46Stangaac       HasFeatureSCQ = true;
34160e5cfe2SWeining Lu   }
34260e5cfe2SWeining Lu   return true;
34360e5cfe2SWeining Lu }
344f62c9252SWeining Lu 
345f62c9252SWeining Lu bool LoongArchTargetInfo::isValidCPUName(StringRef Name) const {
346f62c9252SWeining Lu   return llvm::LoongArch::isValidCPUName(Name);
347f62c9252SWeining Lu }
348f62c9252SWeining Lu 
349f62c9252SWeining Lu void LoongArchTargetInfo::fillValidCPUList(
350f62c9252SWeining Lu     SmallVectorImpl<StringRef> &Values) const {
351f62c9252SWeining Lu   llvm::LoongArch::fillValidCPUList(Values);
352f62c9252SWeining Lu }
353