xref: /freebsd-src/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1bdd1243dSDimitry Andric //===--- LoongArch.cpp - Implement LoongArch target feature support -------===//
2bdd1243dSDimitry Andric //
3bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6bdd1243dSDimitry Andric //
7bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
8bdd1243dSDimitry Andric //
9bdd1243dSDimitry Andric // This file implements LoongArch TargetInfo objects.
10bdd1243dSDimitry Andric //
11bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
12bdd1243dSDimitry Andric 
13bdd1243dSDimitry Andric #include "LoongArch.h"
14bdd1243dSDimitry Andric #include "clang/Basic/Diagnostic.h"
15bdd1243dSDimitry Andric #include "clang/Basic/MacroBuilder.h"
16bdd1243dSDimitry Andric #include "clang/Basic/TargetBuiltins.h"
17bdd1243dSDimitry Andric #include "llvm/Support/raw_ostream.h"
188a4dda33SDimitry Andric #include "llvm/TargetParser/LoongArchTargetParser.h"
19bdd1243dSDimitry Andric 
20bdd1243dSDimitry Andric using namespace clang;
21bdd1243dSDimitry Andric using namespace clang::targets;
22bdd1243dSDimitry Andric 
23bdd1243dSDimitry Andric ArrayRef<const char *> LoongArchTargetInfo::getGCCRegNames() const {
24bdd1243dSDimitry Andric   static const char *const GCCRegNames[] = {
25bdd1243dSDimitry Andric       // General purpose registers.
26bdd1243dSDimitry Andric       "$r0", "$r1", "$r2", "$r3", "$r4", "$r5", "$r6", "$r7", "$r8", "$r9",
27bdd1243dSDimitry Andric       "$r10", "$r11", "$r12", "$r13", "$r14", "$r15", "$r16", "$r17", "$r18",
28bdd1243dSDimitry Andric       "$r19", "$r20", "$r21", "$r22", "$r23", "$r24", "$r25", "$r26", "$r27",
29bdd1243dSDimitry Andric       "$r28", "$r29", "$r30", "$r31",
30bdd1243dSDimitry Andric       // Floating point registers.
31bdd1243dSDimitry Andric       "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", "$f8", "$f9",
32bdd1243dSDimitry Andric       "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", "$f16", "$f17", "$f18",
33bdd1243dSDimitry Andric       "$f19", "$f20", "$f21", "$f22", "$f23", "$f24", "$f25", "$f26", "$f27",
3406c3fb27SDimitry Andric       "$f28", "$f29", "$f30", "$f31",
3506c3fb27SDimitry Andric       // Condition flag registers.
3606c3fb27SDimitry Andric       "$fcc0", "$fcc1", "$fcc2", "$fcc3", "$fcc4", "$fcc5", "$fcc6", "$fcc7",
3706c3fb27SDimitry Andric       // 128-bit vector registers.
3806c3fb27SDimitry Andric       "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6", "$vr7", "$vr8",
3906c3fb27SDimitry Andric       "$vr9", "$vr10", "$vr11", "$vr12", "$vr13", "$vr14", "$vr15", "$vr16",
4006c3fb27SDimitry Andric       "$vr17", "$vr18", "$vr19", "$vr20", "$vr21", "$vr22", "$vr23", "$vr24",
4106c3fb27SDimitry Andric       "$vr25", "$vr26", "$vr27", "$vr28", "$vr29", "$vr30", "$vr31",
4206c3fb27SDimitry Andric       // 256-bit vector registers.
4306c3fb27SDimitry Andric       "$xr0", "$xr1", "$xr2", "$xr3", "$xr4", "$xr5", "$xr6", "$xr7", "$xr8",
4406c3fb27SDimitry Andric       "$xr9", "$xr10", "$xr11", "$xr12", "$xr13", "$xr14", "$xr15", "$xr16",
4506c3fb27SDimitry Andric       "$xr17", "$xr18", "$xr19", "$xr20", "$xr21", "$xr22", "$xr23", "$xr24",
4606c3fb27SDimitry Andric       "$xr25", "$xr26", "$xr27", "$xr28", "$xr29", "$xr30", "$xr31"};
47bdd1243dSDimitry Andric   return llvm::ArrayRef(GCCRegNames);
48bdd1243dSDimitry Andric }
49bdd1243dSDimitry Andric 
50bdd1243dSDimitry Andric ArrayRef<TargetInfo::GCCRegAlias>
51bdd1243dSDimitry Andric LoongArchTargetInfo::getGCCRegAliases() const {
52bdd1243dSDimitry Andric   static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
5306c3fb27SDimitry Andric       {{"zero", "$zero", "r0"}, "$r0"},
5406c3fb27SDimitry Andric       {{"ra", "$ra", "r1"}, "$r1"},
5506c3fb27SDimitry Andric       {{"tp", "$tp", "r2"}, "$r2"},
5606c3fb27SDimitry Andric       {{"sp", "$sp", "r3"}, "$r3"},
5706c3fb27SDimitry Andric       {{"a0", "$a0", "r4"}, "$r4"},
5806c3fb27SDimitry Andric       {{"a1", "$a1", "r5"}, "$r5"},
5906c3fb27SDimitry Andric       {{"a2", "$a2", "r6"}, "$r6"},
6006c3fb27SDimitry Andric       {{"a3", "$a3", "r7"}, "$r7"},
6106c3fb27SDimitry Andric       {{"a4", "$a4", "r8"}, "$r8"},
6206c3fb27SDimitry Andric       {{"a5", "$a5", "r9"}, "$r9"},
6306c3fb27SDimitry Andric       {{"a6", "$a6", "r10"}, "$r10"},
6406c3fb27SDimitry Andric       {{"a7", "$a7", "r11"}, "$r11"},
6506c3fb27SDimitry Andric       {{"t0", "$t0", "r12"}, "$r12"},
6606c3fb27SDimitry Andric       {{"t1", "$t1", "r13"}, "$r13"},
6706c3fb27SDimitry Andric       {{"t2", "$t2", "r14"}, "$r14"},
6806c3fb27SDimitry Andric       {{"t3", "$t3", "r15"}, "$r15"},
6906c3fb27SDimitry Andric       {{"t4", "$t4", "r16"}, "$r16"},
7006c3fb27SDimitry Andric       {{"t5", "$t5", "r17"}, "$r17"},
7106c3fb27SDimitry Andric       {{"t6", "$t6", "r18"}, "$r18"},
7206c3fb27SDimitry Andric       {{"t7", "$t7", "r19"}, "$r19"},
7306c3fb27SDimitry Andric       {{"t8", "$t8", "r20"}, "$r20"},
7406c3fb27SDimitry Andric       {{"r21"}, "$r21"},
7506c3fb27SDimitry Andric       {{"s9", "$s9", "r22", "fp", "$fp"}, "$r22"},
7606c3fb27SDimitry Andric       {{"s0", "$s0", "r23"}, "$r23"},
7706c3fb27SDimitry Andric       {{"s1", "$s1", "r24"}, "$r24"},
7806c3fb27SDimitry Andric       {{"s2", "$s2", "r25"}, "$r25"},
7906c3fb27SDimitry Andric       {{"s3", "$s3", "r26"}, "$r26"},
8006c3fb27SDimitry Andric       {{"s4", "$s4", "r27"}, "$r27"},
8106c3fb27SDimitry Andric       {{"s5", "$s5", "r28"}, "$r28"},
8206c3fb27SDimitry Andric       {{"s6", "$s6", "r29"}, "$r29"},
8306c3fb27SDimitry Andric       {{"s7", "$s7", "r30"}, "$r30"},
8406c3fb27SDimitry Andric       {{"s8", "$s8", "r31"}, "$r31"},
8506c3fb27SDimitry Andric       {{"$fa0"}, "$f0"},
8606c3fb27SDimitry Andric       {{"$fa1"}, "$f1"},
8706c3fb27SDimitry Andric       {{"$fa2"}, "$f2"},
8806c3fb27SDimitry Andric       {{"$fa3"}, "$f3"},
8906c3fb27SDimitry Andric       {{"$fa4"}, "$f4"},
9006c3fb27SDimitry Andric       {{"$fa5"}, "$f5"},
9106c3fb27SDimitry Andric       {{"$fa6"}, "$f6"},
9206c3fb27SDimitry Andric       {{"$fa7"}, "$f7"},
9306c3fb27SDimitry Andric       {{"$ft0"}, "$f8"},
9406c3fb27SDimitry Andric       {{"$ft1"}, "$f9"},
9506c3fb27SDimitry Andric       {{"$ft2"}, "$f10"},
9606c3fb27SDimitry Andric       {{"$ft3"}, "$f11"},
9706c3fb27SDimitry Andric       {{"$ft4"}, "$f12"},
9806c3fb27SDimitry Andric       {{"$ft5"}, "$f13"},
9906c3fb27SDimitry Andric       {{"$ft6"}, "$f14"},
10006c3fb27SDimitry Andric       {{"$ft7"}, "$f15"},
10106c3fb27SDimitry Andric       {{"$ft8"}, "$f16"},
10206c3fb27SDimitry Andric       {{"$ft9"}, "$f17"},
10306c3fb27SDimitry Andric       {{"$ft10"}, "$f18"},
10406c3fb27SDimitry Andric       {{"$ft11"}, "$f19"},
10506c3fb27SDimitry Andric       {{"$ft12"}, "$f20"},
10606c3fb27SDimitry Andric       {{"$ft13"}, "$f21"},
10706c3fb27SDimitry Andric       {{"$ft14"}, "$f22"},
10806c3fb27SDimitry Andric       {{"$ft15"}, "$f23"},
10906c3fb27SDimitry Andric       {{"$fs0"}, "$f24"},
11006c3fb27SDimitry Andric       {{"$fs1"}, "$f25"},
11106c3fb27SDimitry Andric       {{"$fs2"}, "$f26"},
11206c3fb27SDimitry Andric       {{"$fs3"}, "$f27"},
11306c3fb27SDimitry Andric       {{"$fs4"}, "$f28"},
11406c3fb27SDimitry Andric       {{"$fs5"}, "$f29"},
11506c3fb27SDimitry Andric       {{"$fs6"}, "$f30"},
11606c3fb27SDimitry Andric       {{"$fs7"}, "$f31"},
117bdd1243dSDimitry Andric   };
118bdd1243dSDimitry Andric   return llvm::ArrayRef(GCCRegAliases);
119bdd1243dSDimitry Andric }
120bdd1243dSDimitry Andric 
121bdd1243dSDimitry Andric bool LoongArchTargetInfo::validateAsmConstraint(
122bdd1243dSDimitry Andric     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
123bdd1243dSDimitry Andric   // See the GCC definitions here:
124bdd1243dSDimitry Andric   // https://gcc.gnu.org/onlinedocs/gccint/Machine-Constraints.html
125bdd1243dSDimitry Andric   // Note that the 'm' constraint is handled in TargetInfo.
126bdd1243dSDimitry Andric   switch (*Name) {
127bdd1243dSDimitry Andric   default:
128bdd1243dSDimitry Andric     return false;
129bdd1243dSDimitry Andric   case 'f':
130bdd1243dSDimitry Andric     // A floating-point register (if available).
131bdd1243dSDimitry Andric     Info.setAllowsRegister();
132bdd1243dSDimitry Andric     return true;
133bdd1243dSDimitry Andric   case 'k':
134bdd1243dSDimitry Andric     // A memory operand whose address is formed by a base register and
135bdd1243dSDimitry Andric     // (optionally scaled) index register.
136bdd1243dSDimitry Andric     Info.setAllowsMemory();
137bdd1243dSDimitry Andric     return true;
138bdd1243dSDimitry Andric   case 'l':
139bdd1243dSDimitry Andric     // A signed 16-bit constant.
140bdd1243dSDimitry Andric     Info.setRequiresImmediate(-32768, 32767);
141bdd1243dSDimitry Andric     return true;
142bdd1243dSDimitry Andric   case 'I':
143bdd1243dSDimitry Andric     // A signed 12-bit constant (for arithmetic instructions).
144bdd1243dSDimitry Andric     Info.setRequiresImmediate(-2048, 2047);
145bdd1243dSDimitry Andric     return true;
146bdd1243dSDimitry Andric   case 'J':
147bdd1243dSDimitry Andric     // Integer zero.
148bdd1243dSDimitry Andric     Info.setRequiresImmediate(0);
149bdd1243dSDimitry Andric     return true;
150bdd1243dSDimitry Andric   case 'K':
151bdd1243dSDimitry Andric     // An unsigned 12-bit constant (for logic instructions).
152bdd1243dSDimitry Andric     Info.setRequiresImmediate(0, 4095);
153bdd1243dSDimitry Andric     return true;
154bdd1243dSDimitry Andric   case 'Z':
155bdd1243dSDimitry Andric     // ZB: An address that is held in a general-purpose register. The offset is
156bdd1243dSDimitry Andric     //     zero.
157bdd1243dSDimitry Andric     // ZC: A memory operand whose address is formed by a base register
158bdd1243dSDimitry Andric     //     and offset that is suitable for use in instructions with the same
159bdd1243dSDimitry Andric     //     addressing mode as ll.w and sc.w.
160bdd1243dSDimitry Andric     if (Name[1] == 'C' || Name[1] == 'B') {
161bdd1243dSDimitry Andric       Info.setAllowsMemory();
162bdd1243dSDimitry Andric       ++Name; // Skip over 'Z'.
163bdd1243dSDimitry Andric       return true;
164bdd1243dSDimitry Andric     }
165bdd1243dSDimitry Andric     return false;
166bdd1243dSDimitry Andric   }
167bdd1243dSDimitry Andric }
168bdd1243dSDimitry Andric 
169bdd1243dSDimitry Andric std::string
170bdd1243dSDimitry Andric LoongArchTargetInfo::convertConstraint(const char *&Constraint) const {
171bdd1243dSDimitry Andric   std::string R;
172bdd1243dSDimitry Andric   switch (*Constraint) {
173bdd1243dSDimitry Andric   case 'Z':
174bdd1243dSDimitry Andric     // "ZC"/"ZB" are two-character constraints; add "^" hint for later
175bdd1243dSDimitry Andric     // parsing.
176bdd1243dSDimitry Andric     R = "^" + std::string(Constraint, 2);
177bdd1243dSDimitry Andric     ++Constraint;
178bdd1243dSDimitry Andric     break;
179bdd1243dSDimitry Andric   default:
180bdd1243dSDimitry Andric     R = TargetInfo::convertConstraint(Constraint);
181bdd1243dSDimitry Andric     break;
182bdd1243dSDimitry Andric   }
183bdd1243dSDimitry Andric   return R;
184bdd1243dSDimitry Andric }
185bdd1243dSDimitry Andric 
186bdd1243dSDimitry Andric void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts,
187bdd1243dSDimitry Andric                                            MacroBuilder &Builder) const {
188bdd1243dSDimitry Andric   Builder.defineMacro("__loongarch__");
189bdd1243dSDimitry Andric   unsigned GRLen = getRegisterWidth();
190bdd1243dSDimitry Andric   Builder.defineMacro("__loongarch_grlen", Twine(GRLen));
191bdd1243dSDimitry Andric   if (GRLen == 64)
192bdd1243dSDimitry Andric     Builder.defineMacro("__loongarch64");
193bdd1243dSDimitry Andric 
194bdd1243dSDimitry Andric   if (HasFeatureD)
195bdd1243dSDimitry Andric     Builder.defineMacro("__loongarch_frlen", "64");
196bdd1243dSDimitry Andric   else if (HasFeatureF)
197bdd1243dSDimitry Andric     Builder.defineMacro("__loongarch_frlen", "32");
198bdd1243dSDimitry Andric   else
199bdd1243dSDimitry Andric     Builder.defineMacro("__loongarch_frlen", "0");
200bdd1243dSDimitry Andric 
2018a4dda33SDimitry Andric   // Define __loongarch_arch.
2028a4dda33SDimitry Andric   StringRef ArchName = getCPU();
203*0fca6ea1SDimitry Andric   if (ArchName == "loongarch64") {
204*0fca6ea1SDimitry Andric     if (HasFeatureLSX) {
205*0fca6ea1SDimitry Andric       // TODO: As more features of the V1.1 ISA are supported, a unified "v1.1"
206*0fca6ea1SDimitry Andric       // arch feature set will be used to include all sub-features belonging to
207*0fca6ea1SDimitry Andric       // the V1.1 ISA version.
208*0fca6ea1SDimitry Andric       if (HasFeatureFrecipe)
209*0fca6ea1SDimitry Andric         Builder.defineMacro("__loongarch_arch",
210*0fca6ea1SDimitry Andric                             Twine('"') + "la64v1.1" + Twine('"'));
211*0fca6ea1SDimitry Andric       else
212*0fca6ea1SDimitry Andric         Builder.defineMacro("__loongarch_arch",
213*0fca6ea1SDimitry Andric                             Twine('"') + "la64v1.0" + Twine('"'));
214*0fca6ea1SDimitry Andric     } else {
215*0fca6ea1SDimitry Andric       Builder.defineMacro("__loongarch_arch",
216*0fca6ea1SDimitry Andric                           Twine('"') + ArchName + Twine('"'));
217*0fca6ea1SDimitry Andric     }
218*0fca6ea1SDimitry Andric   } else {
2198a4dda33SDimitry Andric     Builder.defineMacro("__loongarch_arch", Twine('"') + ArchName + Twine('"'));
220*0fca6ea1SDimitry Andric   }
2218a4dda33SDimitry Andric 
2228a4dda33SDimitry Andric   // Define __loongarch_tune.
2238a4dda33SDimitry Andric   StringRef TuneCPU = getTargetOpts().TuneCPU;
2248a4dda33SDimitry Andric   if (TuneCPU.empty())
2258a4dda33SDimitry Andric     TuneCPU = ArchName;
2268a4dda33SDimitry Andric   Builder.defineMacro("__loongarch_tune", Twine('"') + TuneCPU + Twine('"'));
227bdd1243dSDimitry Andric 
228*0fca6ea1SDimitry Andric   if (HasFeatureLASX) {
229*0fca6ea1SDimitry Andric     Builder.defineMacro("__loongarch_simd_width", "256");
2305f757f3fSDimitry Andric     Builder.defineMacro("__loongarch_sx", Twine(1));
2315f757f3fSDimitry Andric     Builder.defineMacro("__loongarch_asx", Twine(1));
232*0fca6ea1SDimitry Andric   } else if (HasFeatureLSX) {
233*0fca6ea1SDimitry Andric     Builder.defineMacro("__loongarch_simd_width", "128");
234*0fca6ea1SDimitry Andric     Builder.defineMacro("__loongarch_sx", Twine(1));
235*0fca6ea1SDimitry Andric   }
236*0fca6ea1SDimitry Andric   if (HasFeatureFrecipe)
237*0fca6ea1SDimitry Andric     Builder.defineMacro("__loongarch_frecipe", Twine(1));
2385f757f3fSDimitry Andric 
239bdd1243dSDimitry Andric   StringRef ABI = getABI();
240bdd1243dSDimitry Andric   if (ABI == "lp64d" || ABI == "lp64f" || ABI == "lp64s")
241bdd1243dSDimitry Andric     Builder.defineMacro("__loongarch_lp64");
242bdd1243dSDimitry Andric 
243bdd1243dSDimitry Andric   if (ABI == "lp64d" || ABI == "ilp32d") {
244bdd1243dSDimitry Andric     Builder.defineMacro("__loongarch_hard_float");
245bdd1243dSDimitry Andric     Builder.defineMacro("__loongarch_double_float");
246bdd1243dSDimitry Andric   } else if (ABI == "lp64f" || ABI == "ilp32f") {
247bdd1243dSDimitry Andric     Builder.defineMacro("__loongarch_hard_float");
248bdd1243dSDimitry Andric     Builder.defineMacro("__loongarch_single_float");
249bdd1243dSDimitry Andric   } else if (ABI == "lp64s" || ABI == "ilp32s") {
250bdd1243dSDimitry Andric     Builder.defineMacro("__loongarch_soft_float");
251bdd1243dSDimitry Andric   }
252bdd1243dSDimitry Andric 
253bdd1243dSDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
254bdd1243dSDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
255bdd1243dSDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
256bdd1243dSDimitry Andric   if (GRLen == 64)
257bdd1243dSDimitry Andric     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
258bdd1243dSDimitry Andric }
259bdd1243dSDimitry Andric 
260bdd1243dSDimitry Andric static constexpr Builtin::Info BuiltinInfo[] = {
261bdd1243dSDimitry Andric #define BUILTIN(ID, TYPE, ATTRS)                                               \
262bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
263bdd1243dSDimitry Andric #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
264bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
265bdd1243dSDimitry Andric #include "clang/Basic/BuiltinsLoongArch.def"
266bdd1243dSDimitry Andric };
267bdd1243dSDimitry Andric 
268bdd1243dSDimitry Andric bool LoongArchTargetInfo::initFeatureMap(
269bdd1243dSDimitry Andric     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
270bdd1243dSDimitry Andric     const std::vector<std::string> &FeaturesVec) const {
271bdd1243dSDimitry Andric   if (getTriple().getArch() == llvm::Triple::loongarch64)
272bdd1243dSDimitry Andric     Features["64bit"] = true;
273bdd1243dSDimitry Andric   if (getTriple().getArch() == llvm::Triple::loongarch32)
274bdd1243dSDimitry Andric     Features["32bit"] = true;
275bdd1243dSDimitry Andric 
276bdd1243dSDimitry Andric   return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
277bdd1243dSDimitry Andric }
278bdd1243dSDimitry Andric 
279bdd1243dSDimitry Andric /// Return true if has this feature.
280bdd1243dSDimitry Andric bool LoongArchTargetInfo::hasFeature(StringRef Feature) const {
281bdd1243dSDimitry Andric   bool Is64Bit = getTriple().getArch() == llvm::Triple::loongarch64;
282bdd1243dSDimitry Andric   // TODO: Handle more features.
283bdd1243dSDimitry Andric   return llvm::StringSwitch<bool>(Feature)
284bdd1243dSDimitry Andric       .Case("loongarch32", !Is64Bit)
285bdd1243dSDimitry Andric       .Case("loongarch64", Is64Bit)
286bdd1243dSDimitry Andric       .Case("32bit", !Is64Bit)
287bdd1243dSDimitry Andric       .Case("64bit", Is64Bit)
2885f757f3fSDimitry Andric       .Case("lsx", HasFeatureLSX)
2895f757f3fSDimitry Andric       .Case("lasx", HasFeatureLASX)
290bdd1243dSDimitry Andric       .Default(false);
291bdd1243dSDimitry Andric }
292bdd1243dSDimitry Andric 
293bdd1243dSDimitry Andric ArrayRef<Builtin::Info> LoongArchTargetInfo::getTargetBuiltins() const {
294bdd1243dSDimitry Andric   return llvm::ArrayRef(BuiltinInfo, clang::LoongArch::LastTSBuiltin -
295bdd1243dSDimitry Andric                                          Builtin::FirstTSBuiltin);
296bdd1243dSDimitry Andric }
297bdd1243dSDimitry Andric 
298bdd1243dSDimitry Andric bool LoongArchTargetInfo::handleTargetFeatures(
299bdd1243dSDimitry Andric     std::vector<std::string> &Features, DiagnosticsEngine &Diags) {
300bdd1243dSDimitry Andric   for (const auto &Feature : Features) {
301bdd1243dSDimitry Andric     if (Feature == "+d" || Feature == "+f") {
302bdd1243dSDimitry Andric       // "d" implies "f".
303bdd1243dSDimitry Andric       HasFeatureF = true;
304bdd1243dSDimitry Andric       if (Feature == "+d") {
305bdd1243dSDimitry Andric         HasFeatureD = true;
306bdd1243dSDimitry Andric       }
3075f757f3fSDimitry Andric     } else if (Feature == "+lsx")
3085f757f3fSDimitry Andric       HasFeatureLSX = true;
3095f757f3fSDimitry Andric     else if (Feature == "+lasx")
3105f757f3fSDimitry Andric       HasFeatureLASX = true;
311*0fca6ea1SDimitry Andric     else if (Feature == "-ual")
312*0fca6ea1SDimitry Andric       HasUnalignedAccess = false;
313*0fca6ea1SDimitry Andric     else if (Feature == "+frecipe")
314*0fca6ea1SDimitry Andric       HasFeatureFrecipe = true;
315bdd1243dSDimitry Andric   }
316bdd1243dSDimitry Andric   return true;
317bdd1243dSDimitry Andric }
3188a4dda33SDimitry Andric 
3198a4dda33SDimitry Andric bool LoongArchTargetInfo::isValidCPUName(StringRef Name) const {
3208a4dda33SDimitry Andric   return llvm::LoongArch::isValidCPUName(Name);
3218a4dda33SDimitry Andric }
3228a4dda33SDimitry Andric 
3238a4dda33SDimitry Andric void LoongArchTargetInfo::fillValidCPUList(
3248a4dda33SDimitry Andric     SmallVectorImpl<StringRef> &Values) const {
3258a4dda33SDimitry Andric   llvm::LoongArch::fillValidCPUList(Values);
3268a4dda33SDimitry Andric }
327