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