121bce900SZi Xuan Wu //===-- TargetParser - Parser for target features ---------------*- C++ -*-===//
221bce900SZi Xuan Wu //
321bce900SZi Xuan Wu //                     The LLVM Compiler Infrastructure
421bce900SZi Xuan Wu //
521bce900SZi Xuan Wu // This file is distributed under the University of Illinois Open Source
621bce900SZi Xuan Wu // License. See LICENSE.TXT for details.
721bce900SZi Xuan Wu //
821bce900SZi Xuan Wu //===----------------------------------------------------------------------===//
921bce900SZi Xuan Wu //
1021bce900SZi Xuan Wu // This file implements a target parser to recognise CSKY hardware features
1121bce900SZi Xuan Wu // such as CPU/ARCH names.
1221bce900SZi Xuan Wu //
1321bce900SZi Xuan Wu //===----------------------------------------------------------------------===//
1421bce900SZi Xuan Wu 
1521bce900SZi Xuan Wu #include "llvm/Support/CSKYTargetParser.h"
1621bce900SZi Xuan Wu #include "llvm/ADT/StringSwitch.h"
1721bce900SZi Xuan Wu 
1821bce900SZi Xuan Wu using namespace llvm;
1921bce900SZi Xuan Wu 
getFPUFeatures(CSKYFPUKind CSKYFPUKind,std::vector<StringRef> & Features)2021bce900SZi Xuan Wu bool CSKY::getFPUFeatures(CSKYFPUKind CSKYFPUKind,
2121bce900SZi Xuan Wu                           std::vector<StringRef> &Features) {
2221bce900SZi Xuan Wu 
2321bce900SZi Xuan Wu   if (CSKYFPUKind >= FK_LAST || CSKYFPUKind == FK_INVALID)
2421bce900SZi Xuan Wu     return false;
2521bce900SZi Xuan Wu 
2621bce900SZi Xuan Wu   switch (CSKYFPUKind) {
2721bce900SZi Xuan Wu   case FK_AUTO:
2821bce900SZi Xuan Wu     Features.push_back("+fpuv2_sf");
2921bce900SZi Xuan Wu     Features.push_back("+fpuv2_df");
3021bce900SZi Xuan Wu     Features.push_back("+fdivdu");
3121bce900SZi Xuan Wu     break;
3221bce900SZi Xuan Wu   case FK_FPV2:
3321bce900SZi Xuan Wu     Features.push_back("+fpuv2_sf");
3421bce900SZi Xuan Wu     Features.push_back("+fpuv2_df");
3521bce900SZi Xuan Wu     break;
3621bce900SZi Xuan Wu   case FK_FPV2_DIVD:
3721bce900SZi Xuan Wu     Features.push_back("+fpuv2_sf");
3821bce900SZi Xuan Wu     Features.push_back("+fpuv2_df");
3921bce900SZi Xuan Wu     Features.push_back("+fdivdu");
4021bce900SZi Xuan Wu     break;
4121bce900SZi Xuan Wu   case FK_FPV2_SF:
4221bce900SZi Xuan Wu     Features.push_back("+fpuv2_sf");
4321bce900SZi Xuan Wu     break;
4421bce900SZi Xuan Wu   case FK_FPV3:
4521bce900SZi Xuan Wu     Features.push_back("+fpuv3_hf");
46*b86440ecSZi Xuan Wu (Zeson)     Features.push_back("+fpuv3_hi");
4721bce900SZi Xuan Wu     Features.push_back("+fpuv3_sf");
4821bce900SZi Xuan Wu     Features.push_back("+fpuv3_df");
4921bce900SZi Xuan Wu     break;
5021bce900SZi Xuan Wu   case FK_FPV3_HF:
5121bce900SZi Xuan Wu     Features.push_back("+fpuv3_hf");
52*b86440ecSZi Xuan Wu (Zeson)     Features.push_back("+fpuv3_hi");
5321bce900SZi Xuan Wu     break;
5421bce900SZi Xuan Wu   case FK_FPV3_HSF:
5521bce900SZi Xuan Wu     Features.push_back("+fpuv3_hf");
56*b86440ecSZi Xuan Wu (Zeson)     Features.push_back("+fpuv3_hi");
5721bce900SZi Xuan Wu     Features.push_back("+fpuv3_sf");
5821bce900SZi Xuan Wu     break;
5921bce900SZi Xuan Wu   case FK_FPV3_SDF:
6021bce900SZi Xuan Wu     Features.push_back("+fpuv3_sf");
6121bce900SZi Xuan Wu     Features.push_back("+fpuv3_df");
6221bce900SZi Xuan Wu     break;
6321bce900SZi Xuan Wu   default:
6421bce900SZi Xuan Wu     llvm_unreachable("Unknown FPU Kind");
6521bce900SZi Xuan Wu     return false;
6621bce900SZi Xuan Wu   }
6721bce900SZi Xuan Wu 
6821bce900SZi Xuan Wu   return true;
6921bce900SZi Xuan Wu }
7021bce900SZi Xuan Wu 
7121bce900SZi Xuan Wu // ======================================================= //
7221bce900SZi Xuan Wu // Information by ID
7321bce900SZi Xuan Wu // ======================================================= //
7421bce900SZi Xuan Wu 
getArchName(ArchKind AK)7521bce900SZi Xuan Wu StringRef CSKY::getArchName(ArchKind AK) {
7621bce900SZi Xuan Wu   return ARCHNames[static_cast<unsigned>(AK)].getName();
7721bce900SZi Xuan Wu }
7821bce900SZi Xuan Wu 
7921bce900SZi Xuan Wu // The default cpu's name is same as arch name.
getDefaultCPU(StringRef Arch)8021bce900SZi Xuan Wu StringRef CSKY::getDefaultCPU(StringRef Arch) {
8121bce900SZi Xuan Wu   ArchKind AK = parseArch(Arch);
8221bce900SZi Xuan Wu   if (AK == CSKY::ArchKind::INVALID)
8321bce900SZi Xuan Wu     return StringRef();
8421bce900SZi Xuan Wu 
8521bce900SZi Xuan Wu   return Arch;
8621bce900SZi Xuan Wu }
8721bce900SZi Xuan Wu 
8821bce900SZi Xuan Wu // ======================================================= //
8921bce900SZi Xuan Wu // Parsers
9021bce900SZi Xuan Wu // ======================================================= //
parseArch(StringRef Arch)9121bce900SZi Xuan Wu CSKY::ArchKind CSKY::parseArch(StringRef Arch) {
9221bce900SZi Xuan Wu   for (const auto A : ARCHNames) {
9321bce900SZi Xuan Wu     if (A.getName() == Arch)
9421bce900SZi Xuan Wu       return A.ID;
9521bce900SZi Xuan Wu   }
9621bce900SZi Xuan Wu 
9721bce900SZi Xuan Wu   return CSKY::ArchKind::INVALID;
9821bce900SZi Xuan Wu }
9921bce900SZi Xuan Wu 
parseCPUArch(StringRef CPU)10021bce900SZi Xuan Wu CSKY::ArchKind CSKY::parseCPUArch(StringRef CPU) {
10121bce900SZi Xuan Wu   for (const auto C : CPUNames) {
10221bce900SZi Xuan Wu     if (CPU == C.getName())
10321bce900SZi Xuan Wu       return C.ArchID;
10421bce900SZi Xuan Wu   }
10521bce900SZi Xuan Wu 
10621bce900SZi Xuan Wu   return CSKY::ArchKind::INVALID;
10721bce900SZi Xuan Wu }
10821bce900SZi Xuan Wu 
parseArchExt(StringRef ArchExt)10921bce900SZi Xuan Wu uint64_t CSKY::parseArchExt(StringRef ArchExt) {
11021bce900SZi Xuan Wu   for (const auto &A : CSKYARCHExtNames) {
11121bce900SZi Xuan Wu     if (ArchExt == A.getName())
11221bce900SZi Xuan Wu       return A.ID;
11321bce900SZi Xuan Wu   }
11421bce900SZi Xuan Wu   return AEK_INVALID;
11521bce900SZi Xuan Wu }
11621bce900SZi Xuan Wu 
fillValidCPUArchList(SmallVectorImpl<StringRef> & Values)11721bce900SZi Xuan Wu void CSKY::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
11821bce900SZi Xuan Wu   for (const CpuNames<CSKY::ArchKind> &Arch : CPUNames) {
11921bce900SZi Xuan Wu     if (Arch.ArchID != CSKY::ArchKind::INVALID)
12021bce900SZi Xuan Wu       Values.push_back(Arch.getName());
12121bce900SZi Xuan Wu   }
12221bce900SZi Xuan Wu }
12321bce900SZi Xuan Wu 
getFPUName(unsigned FPUKind)12421bce900SZi Xuan Wu StringRef CSKY::getFPUName(unsigned FPUKind) {
12521bce900SZi Xuan Wu   if (FPUKind >= FK_LAST)
12621bce900SZi Xuan Wu     return StringRef();
12721bce900SZi Xuan Wu   return FPUNames[FPUKind].getName();
12821bce900SZi Xuan Wu }
12921bce900SZi Xuan Wu 
getFPUVersion(unsigned FPUKind)13021bce900SZi Xuan Wu CSKY::FPUVersion CSKY::getFPUVersion(unsigned FPUKind) {
13121bce900SZi Xuan Wu   if (FPUKind >= FK_LAST)
13221bce900SZi Xuan Wu     return FPUVersion::NONE;
13321bce900SZi Xuan Wu   return FPUNames[FPUKind].FPUVer;
13421bce900SZi Xuan Wu }
13521bce900SZi Xuan Wu 
getDefaultExtensions(StringRef CPU)13621bce900SZi Xuan Wu uint64_t CSKY::getDefaultExtensions(StringRef CPU) {
13721bce900SZi Xuan Wu   return StringSwitch<uint64_t>(CPU)
13821bce900SZi Xuan Wu #define CSKY_CPU_NAME(NAME, ID, DEFAULT_EXT)                                   \
13921bce900SZi Xuan Wu   .Case(NAME, ARCHNames[static_cast<unsigned>(ArchKind::ID)].archBaseExt |     \
14021bce900SZi Xuan Wu                   DEFAULT_EXT)
14121bce900SZi Xuan Wu #include "llvm/Support/CSKYTargetParser.def"
14221bce900SZi Xuan Wu       .Default(CSKY::AEK_INVALID);
14321bce900SZi Xuan Wu }
14421bce900SZi Xuan Wu 
getArchExtName(uint64_t ArchExtKind)14521bce900SZi Xuan Wu StringRef CSKY::getArchExtName(uint64_t ArchExtKind) {
14621bce900SZi Xuan Wu   for (const auto &AE : CSKYARCHExtNames)
14721bce900SZi Xuan Wu     if (ArchExtKind == AE.ID)
14821bce900SZi Xuan Wu       return AE.getName();
14921bce900SZi Xuan Wu   return StringRef();
15021bce900SZi Xuan Wu }
15121bce900SZi Xuan Wu 
stripNegationPrefix(StringRef & Name)15221bce900SZi Xuan Wu static bool stripNegationPrefix(StringRef &Name) {
15321bce900SZi Xuan Wu   if (Name.startswith("no")) {
15421bce900SZi Xuan Wu     Name = Name.substr(2);
15521bce900SZi Xuan Wu     return true;
15621bce900SZi Xuan Wu   }
15721bce900SZi Xuan Wu   return false;
15821bce900SZi Xuan Wu }
15921bce900SZi Xuan Wu 
getArchExtFeature(StringRef ArchExt)16021bce900SZi Xuan Wu StringRef CSKY::getArchExtFeature(StringRef ArchExt) {
16121bce900SZi Xuan Wu   bool Negated = stripNegationPrefix(ArchExt);
16221bce900SZi Xuan Wu   for (const auto &AE : CSKYARCHExtNames) {
16321bce900SZi Xuan Wu     if (AE.Feature && ArchExt == AE.getName())
16421bce900SZi Xuan Wu       return StringRef(Negated ? AE.NegFeature : AE.Feature);
16521bce900SZi Xuan Wu   }
16621bce900SZi Xuan Wu 
16721bce900SZi Xuan Wu   return StringRef();
16821bce900SZi Xuan Wu }
16921bce900SZi Xuan Wu 
getExtensionFeatures(uint64_t Extensions,std::vector<StringRef> & Features)17021bce900SZi Xuan Wu bool CSKY::getExtensionFeatures(uint64_t Extensions,
17121bce900SZi Xuan Wu                                 std::vector<StringRef> &Features) {
17221bce900SZi Xuan Wu   if (Extensions == CSKY::AEK_INVALID)
17321bce900SZi Xuan Wu     return false;
17421bce900SZi Xuan Wu 
17521bce900SZi Xuan Wu   for (const auto &AE : CSKYARCHExtNames) {
17621bce900SZi Xuan Wu     if ((Extensions & AE.ID) == AE.ID && AE.Feature)
17721bce900SZi Xuan Wu       Features.push_back(AE.Feature);
17821bce900SZi Xuan Wu   }
17921bce900SZi Xuan Wu 
18021bce900SZi Xuan Wu   return true;
18121bce900SZi Xuan Wu }
182