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