xref: /freebsd/contrib/llvm-project/llvm/lib/TargetParser/CSKYTargetParser.cpp (revision b7daab8be1d4555f23a297e60e4128c01caabf82)
1 //===-- TargetParser - Parser for target features ---------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements a target parser to recognise CSKY hardware features
11 // such as CPU/ARCH names.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "llvm/TargetParser/CSKYTargetParser.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringSwitch.h"
18 
19 using namespace llvm;
20 
21 bool CSKY::getFPUFeatures(CSKYFPUKind CSKYFPUKind,
22                           std::vector<StringRef> &Features) {
23 
24   if (CSKYFPUKind >= FK_LAST || CSKYFPUKind == FK_INVALID)
25     return false;
26 
27   switch (CSKYFPUKind) {
28   case FK_AUTO:
29     Features.push_back("+fpuv2_sf");
30     Features.push_back("+fpuv2_df");
31     Features.push_back("+fdivdu");
32     break;
33   case FK_FPV2:
34     Features.push_back("+fpuv2_sf");
35     Features.push_back("+fpuv2_df");
36     break;
37   case FK_FPV2_DIVD:
38     Features.push_back("+fpuv2_sf");
39     Features.push_back("+fpuv2_df");
40     Features.push_back("+fdivdu");
41     break;
42   case FK_FPV2_SF:
43     Features.push_back("+fpuv2_sf");
44     break;
45   case FK_FPV3:
46     Features.push_back("+fpuv3_hf");
47     Features.push_back("+fpuv3_hi");
48     Features.push_back("+fpuv3_sf");
49     Features.push_back("+fpuv3_df");
50     break;
51   case FK_FPV3_HF:
52     Features.push_back("+fpuv3_hf");
53     Features.push_back("+fpuv3_hi");
54     break;
55   case FK_FPV3_HSF:
56     Features.push_back("+fpuv3_hf");
57     Features.push_back("+fpuv3_hi");
58     Features.push_back("+fpuv3_sf");
59     break;
60   case FK_FPV3_SDF:
61     Features.push_back("+fpuv3_sf");
62     Features.push_back("+fpuv3_df");
63     break;
64   default:
65     llvm_unreachable("Unknown FPU Kind");
66     return false;
67   }
68 
69   return true;
70 }
71 
72 // ======================================================= //
73 // Information by ID
74 // ======================================================= //
75 
76 StringRef CSKY::getArchName(ArchKind AK) {
77   return ARCHNames[static_cast<unsigned>(AK)].getName();
78 }
79 
80 // The default cpu's name is same as arch name.
81 StringRef CSKY::getDefaultCPU(StringRef Arch) {
82   ArchKind AK = parseArch(Arch);
83   if (AK == CSKY::ArchKind::INVALID)
84     return StringRef();
85 
86   return Arch;
87 }
88 
89 // ======================================================= //
90 // Parsers
91 // ======================================================= //
92 CSKY::ArchKind CSKY::parseArch(StringRef Arch) {
93   for (const auto A : ARCHNames) {
94     if (A.getName() == Arch)
95       return A.ID;
96   }
97 
98   return CSKY::ArchKind::INVALID;
99 }
100 
101 CSKY::ArchKind CSKY::parseCPUArch(StringRef CPU) {
102   for (const auto C : CPUNames) {
103     if (CPU == C.getName())
104       return C.ArchID;
105   }
106 
107   return CSKY::ArchKind::INVALID;
108 }
109 
110 uint64_t CSKY::parseArchExt(StringRef ArchExt) {
111   for (const auto &A : CSKYARCHExtNames) {
112     if (ArchExt == A.getName())
113       return A.ID;
114   }
115   return AEK_INVALID;
116 }
117 
118 void CSKY::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
119   for (const CpuNames<CSKY::ArchKind> &Arch : CPUNames) {
120     if (Arch.ArchID != CSKY::ArchKind::INVALID)
121       Values.push_back(Arch.getName());
122   }
123 }
124 
125 StringRef CSKY::getFPUName(unsigned FPUKind) {
126   if (FPUKind >= FK_LAST)
127     return StringRef();
128   return FPUNames[FPUKind].getName();
129 }
130 
131 CSKY::FPUVersion CSKY::getFPUVersion(unsigned FPUKind) {
132   if (FPUKind >= FK_LAST)
133     return FPUVersion::NONE;
134   return FPUNames[FPUKind].FPUVer;
135 }
136 
137 uint64_t CSKY::getDefaultExtensions(StringRef CPU) {
138   return StringSwitch<uint64_t>(CPU)
139 #define CSKY_CPU_NAME(NAME, ID, DEFAULT_EXT)                                   \
140   .Case(NAME, ARCHNames[static_cast<unsigned>(ArchKind::ID)].archBaseExt |     \
141                   DEFAULT_EXT)
142 #include "llvm/TargetParser/CSKYTargetParser.def"
143       .Default(CSKY::AEK_INVALID);
144 }
145 
146 StringRef CSKY::getArchExtName(uint64_t ArchExtKind) {
147   for (const auto &AE : CSKYARCHExtNames)
148     if (ArchExtKind == AE.ID)
149       return AE.getName();
150   return StringRef();
151 }
152 
153 static bool stripNegationPrefix(StringRef &Name) {
154   if (Name.starts_with("no")) {
155     Name = Name.substr(2);
156     return true;
157   }
158   return false;
159 }
160 
161 StringRef CSKY::getArchExtFeature(StringRef ArchExt) {
162   bool Negated = stripNegationPrefix(ArchExt);
163   for (const auto &AE : CSKYARCHExtNames) {
164     if (AE.Feature && ArchExt == AE.getName())
165       return StringRef(Negated ? AE.NegFeature : AE.Feature);
166   }
167 
168   return StringRef();
169 }
170 
171 bool CSKY::getExtensionFeatures(uint64_t Extensions,
172                                 std::vector<StringRef> &Features) {
173   if (Extensions == CSKY::AEK_INVALID)
174     return false;
175 
176   for (const auto &AE : CSKYARCHExtNames) {
177     if ((Extensions & AE.ID) == AE.ID && AE.Feature)
178       Features.push_back(AE.Feature);
179   }
180 
181   return true;
182 }
183