xref: /src/contrib/llvm-project/llvm/lib/TargetParser/CSKYTargetParser.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1145449b1SDimitry Andric //===-- TargetParser - Parser for target features ---------------*- C++ -*-===//
2145449b1SDimitry Andric //
3145449b1SDimitry Andric //                     The LLVM Compiler Infrastructure
4145449b1SDimitry Andric //
5145449b1SDimitry Andric // This file is distributed under the University of Illinois Open Source
6145449b1SDimitry Andric // License. See LICENSE.TXT for details.
7145449b1SDimitry Andric //
8145449b1SDimitry Andric //===----------------------------------------------------------------------===//
9145449b1SDimitry Andric //
10145449b1SDimitry Andric // This file implements a target parser to recognise CSKY hardware features
11145449b1SDimitry Andric // such as CPU/ARCH names.
12145449b1SDimitry Andric //
13145449b1SDimitry Andric //===----------------------------------------------------------------------===//
14145449b1SDimitry Andric 
15e3b55780SDimitry Andric #include "llvm/TargetParser/CSKYTargetParser.h"
16145449b1SDimitry Andric #include "llvm/ADT/StringSwitch.h"
17145449b1SDimitry Andric 
18145449b1SDimitry Andric using namespace llvm;
19145449b1SDimitry Andric 
getFPUFeatures(CSKYFPUKind CSKYFPUKind,std::vector<StringRef> & Features)20145449b1SDimitry Andric bool CSKY::getFPUFeatures(CSKYFPUKind CSKYFPUKind,
21145449b1SDimitry Andric                           std::vector<StringRef> &Features) {
22145449b1SDimitry Andric 
23145449b1SDimitry Andric   if (CSKYFPUKind >= FK_LAST || CSKYFPUKind == FK_INVALID)
24145449b1SDimitry Andric     return false;
25145449b1SDimitry Andric 
26145449b1SDimitry Andric   switch (CSKYFPUKind) {
27145449b1SDimitry Andric   case FK_AUTO:
28145449b1SDimitry Andric     Features.push_back("+fpuv2_sf");
29145449b1SDimitry Andric     Features.push_back("+fpuv2_df");
30145449b1SDimitry Andric     Features.push_back("+fdivdu");
31145449b1SDimitry Andric     break;
32145449b1SDimitry Andric   case FK_FPV2:
33145449b1SDimitry Andric     Features.push_back("+fpuv2_sf");
34145449b1SDimitry Andric     Features.push_back("+fpuv2_df");
35145449b1SDimitry Andric     break;
36145449b1SDimitry Andric   case FK_FPV2_DIVD:
37145449b1SDimitry Andric     Features.push_back("+fpuv2_sf");
38145449b1SDimitry Andric     Features.push_back("+fpuv2_df");
39145449b1SDimitry Andric     Features.push_back("+fdivdu");
40145449b1SDimitry Andric     break;
41145449b1SDimitry Andric   case FK_FPV2_SF:
42145449b1SDimitry Andric     Features.push_back("+fpuv2_sf");
43145449b1SDimitry Andric     break;
44145449b1SDimitry Andric   case FK_FPV3:
45145449b1SDimitry Andric     Features.push_back("+fpuv3_hf");
46145449b1SDimitry Andric     Features.push_back("+fpuv3_hi");
47145449b1SDimitry Andric     Features.push_back("+fpuv3_sf");
48145449b1SDimitry Andric     Features.push_back("+fpuv3_df");
49145449b1SDimitry Andric     break;
50145449b1SDimitry Andric   case FK_FPV3_HF:
51145449b1SDimitry Andric     Features.push_back("+fpuv3_hf");
52145449b1SDimitry Andric     Features.push_back("+fpuv3_hi");
53145449b1SDimitry Andric     break;
54145449b1SDimitry Andric   case FK_FPV3_HSF:
55145449b1SDimitry Andric     Features.push_back("+fpuv3_hf");
56145449b1SDimitry Andric     Features.push_back("+fpuv3_hi");
57145449b1SDimitry Andric     Features.push_back("+fpuv3_sf");
58145449b1SDimitry Andric     break;
59145449b1SDimitry Andric   case FK_FPV3_SDF:
60145449b1SDimitry Andric     Features.push_back("+fpuv3_sf");
61145449b1SDimitry Andric     Features.push_back("+fpuv3_df");
62145449b1SDimitry Andric     break;
63145449b1SDimitry Andric   default:
64145449b1SDimitry Andric     llvm_unreachable("Unknown FPU Kind");
65145449b1SDimitry Andric     return false;
66145449b1SDimitry Andric   }
67145449b1SDimitry Andric 
68145449b1SDimitry Andric   return true;
69145449b1SDimitry Andric }
70145449b1SDimitry Andric 
71145449b1SDimitry Andric // ======================================================= //
72145449b1SDimitry Andric // Information by ID
73145449b1SDimitry Andric // ======================================================= //
74145449b1SDimitry Andric 
getArchName(ArchKind AK)75145449b1SDimitry Andric StringRef CSKY::getArchName(ArchKind AK) {
76145449b1SDimitry Andric   return ARCHNames[static_cast<unsigned>(AK)].getName();
77145449b1SDimitry Andric }
78145449b1SDimitry Andric 
79145449b1SDimitry Andric // The default cpu's name is same as arch name.
getDefaultCPU(StringRef Arch)80145449b1SDimitry Andric StringRef CSKY::getDefaultCPU(StringRef Arch) {
81145449b1SDimitry Andric   ArchKind AK = parseArch(Arch);
82145449b1SDimitry Andric   if (AK == CSKY::ArchKind::INVALID)
83145449b1SDimitry Andric     return StringRef();
84145449b1SDimitry Andric 
85145449b1SDimitry Andric   return Arch;
86145449b1SDimitry Andric }
87145449b1SDimitry Andric 
88145449b1SDimitry Andric // ======================================================= //
89145449b1SDimitry Andric // Parsers
90145449b1SDimitry Andric // ======================================================= //
parseArch(StringRef Arch)91145449b1SDimitry Andric CSKY::ArchKind CSKY::parseArch(StringRef Arch) {
92145449b1SDimitry Andric   for (const auto A : ARCHNames) {
93145449b1SDimitry Andric     if (A.getName() == Arch)
94145449b1SDimitry Andric       return A.ID;
95145449b1SDimitry Andric   }
96145449b1SDimitry Andric 
97145449b1SDimitry Andric   return CSKY::ArchKind::INVALID;
98145449b1SDimitry Andric }
99145449b1SDimitry Andric 
parseCPUArch(StringRef CPU)100145449b1SDimitry Andric CSKY::ArchKind CSKY::parseCPUArch(StringRef CPU) {
101145449b1SDimitry Andric   for (const auto C : CPUNames) {
102145449b1SDimitry Andric     if (CPU == C.getName())
103145449b1SDimitry Andric       return C.ArchID;
104145449b1SDimitry Andric   }
105145449b1SDimitry Andric 
106145449b1SDimitry Andric   return CSKY::ArchKind::INVALID;
107145449b1SDimitry Andric }
108145449b1SDimitry Andric 
parseArchExt(StringRef ArchExt)109145449b1SDimitry Andric uint64_t CSKY::parseArchExt(StringRef ArchExt) {
110145449b1SDimitry Andric   for (const auto &A : CSKYARCHExtNames) {
111145449b1SDimitry Andric     if (ArchExt == A.getName())
112145449b1SDimitry Andric       return A.ID;
113145449b1SDimitry Andric   }
114145449b1SDimitry Andric   return AEK_INVALID;
115145449b1SDimitry Andric }
116145449b1SDimitry Andric 
fillValidCPUArchList(SmallVectorImpl<StringRef> & Values)117145449b1SDimitry Andric void CSKY::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
118145449b1SDimitry Andric   for (const CpuNames<CSKY::ArchKind> &Arch : CPUNames) {
119145449b1SDimitry Andric     if (Arch.ArchID != CSKY::ArchKind::INVALID)
120145449b1SDimitry Andric       Values.push_back(Arch.getName());
121145449b1SDimitry Andric   }
122145449b1SDimitry Andric }
123145449b1SDimitry Andric 
getFPUName(unsigned FPUKind)124145449b1SDimitry Andric StringRef CSKY::getFPUName(unsigned FPUKind) {
125145449b1SDimitry Andric   if (FPUKind >= FK_LAST)
126145449b1SDimitry Andric     return StringRef();
127145449b1SDimitry Andric   return FPUNames[FPUKind].getName();
128145449b1SDimitry Andric }
129145449b1SDimitry Andric 
getFPUVersion(unsigned FPUKind)130145449b1SDimitry Andric CSKY::FPUVersion CSKY::getFPUVersion(unsigned FPUKind) {
131145449b1SDimitry Andric   if (FPUKind >= FK_LAST)
132145449b1SDimitry Andric     return FPUVersion::NONE;
133145449b1SDimitry Andric   return FPUNames[FPUKind].FPUVer;
134145449b1SDimitry Andric }
135145449b1SDimitry Andric 
getDefaultExtensions(StringRef CPU)136145449b1SDimitry Andric uint64_t CSKY::getDefaultExtensions(StringRef CPU) {
137145449b1SDimitry Andric   return StringSwitch<uint64_t>(CPU)
138145449b1SDimitry Andric #define CSKY_CPU_NAME(NAME, ID, DEFAULT_EXT)                                   \
139145449b1SDimitry Andric   .Case(NAME, ARCHNames[static_cast<unsigned>(ArchKind::ID)].archBaseExt |     \
140145449b1SDimitry Andric                   DEFAULT_EXT)
141e3b55780SDimitry Andric #include "llvm/TargetParser/CSKYTargetParser.def"
142145449b1SDimitry Andric       .Default(CSKY::AEK_INVALID);
143145449b1SDimitry Andric }
144145449b1SDimitry Andric 
getArchExtName(uint64_t ArchExtKind)145145449b1SDimitry Andric StringRef CSKY::getArchExtName(uint64_t ArchExtKind) {
146145449b1SDimitry Andric   for (const auto &AE : CSKYARCHExtNames)
147145449b1SDimitry Andric     if (ArchExtKind == AE.ID)
148145449b1SDimitry Andric       return AE.getName();
149145449b1SDimitry Andric   return StringRef();
150145449b1SDimitry Andric }
151145449b1SDimitry Andric 
stripNegationPrefix(StringRef & Name)152145449b1SDimitry Andric static bool stripNegationPrefix(StringRef &Name) {
153312c0ed1SDimitry Andric   if (Name.starts_with("no")) {
154145449b1SDimitry Andric     Name = Name.substr(2);
155145449b1SDimitry Andric     return true;
156145449b1SDimitry Andric   }
157145449b1SDimitry Andric   return false;
158145449b1SDimitry Andric }
159145449b1SDimitry Andric 
getArchExtFeature(StringRef ArchExt)160145449b1SDimitry Andric StringRef CSKY::getArchExtFeature(StringRef ArchExt) {
161145449b1SDimitry Andric   bool Negated = stripNegationPrefix(ArchExt);
162145449b1SDimitry Andric   for (const auto &AE : CSKYARCHExtNames) {
163145449b1SDimitry Andric     if (AE.Feature && ArchExt == AE.getName())
164145449b1SDimitry Andric       return StringRef(Negated ? AE.NegFeature : AE.Feature);
165145449b1SDimitry Andric   }
166145449b1SDimitry Andric 
167145449b1SDimitry Andric   return StringRef();
168145449b1SDimitry Andric }
169145449b1SDimitry Andric 
getExtensionFeatures(uint64_t Extensions,std::vector<StringRef> & Features)170145449b1SDimitry Andric bool CSKY::getExtensionFeatures(uint64_t Extensions,
171145449b1SDimitry Andric                                 std::vector<StringRef> &Features) {
172145449b1SDimitry Andric   if (Extensions == CSKY::AEK_INVALID)
173145449b1SDimitry Andric     return false;
174145449b1SDimitry Andric 
175145449b1SDimitry Andric   for (const auto &AE : CSKYARCHExtNames) {
176145449b1SDimitry Andric     if ((Extensions & AE.ID) == AE.ID && AE.Feature)
177145449b1SDimitry Andric       Features.push_back(AE.Feature);
178145449b1SDimitry Andric   }
179145449b1SDimitry Andric 
180145449b1SDimitry Andric   return true;
181145449b1SDimitry Andric }
182