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