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
19using namespace llvm;
20
21bool 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(x: "+fpuv2_sf");
30 Features.push_back(x: "+fpuv2_df");
31 Features.push_back(x: "+fdivdu");
32 break;
33 case FK_FPV2:
34 Features.push_back(x: "+fpuv2_sf");
35 Features.push_back(x: "+fpuv2_df");
36 break;
37 case FK_FPV2_DIVD:
38 Features.push_back(x: "+fpuv2_sf");
39 Features.push_back(x: "+fpuv2_df");
40 Features.push_back(x: "+fdivdu");
41 break;
42 case FK_FPV2_SF:
43 Features.push_back(x: "+fpuv2_sf");
44 break;
45 case FK_FPV3:
46 Features.push_back(x: "+fpuv3_hf");
47 Features.push_back(x: "+fpuv3_hi");
48 Features.push_back(x: "+fpuv3_sf");
49 Features.push_back(x: "+fpuv3_df");
50 break;
51 case FK_FPV3_HF:
52 Features.push_back(x: "+fpuv3_hf");
53 Features.push_back(x: "+fpuv3_hi");
54 break;
55 case FK_FPV3_HSF:
56 Features.push_back(x: "+fpuv3_hf");
57 Features.push_back(x: "+fpuv3_hi");
58 Features.push_back(x: "+fpuv3_sf");
59 break;
60 case FK_FPV3_SDF:
61 Features.push_back(x: "+fpuv3_sf");
62 Features.push_back(x: "+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
76StringRef 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.
81StringRef 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// ======================================================= //
92CSKY::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
101CSKY::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
110uint64_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
118void CSKY::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
119 for (const CpuNames<CSKY::ArchKind> &Arch : CPUNames) {
120 if (Arch.ArchID != CSKY::ArchKind::INVALID)
121 Values.push_back(Elt: Arch.getName());
122 }
123}
124
125StringRef CSKY::getFPUName(unsigned FPUKind) {
126 if (FPUKind >= FK_LAST)
127 return StringRef();
128 return FPUNames[FPUKind].getName();
129}
130
131CSKY::FPUVersion CSKY::getFPUVersion(unsigned FPUKind) {
132 if (FPUKind >= FK_LAST)
133 return FPUVersion::NONE;
134 return FPUNames[FPUKind].FPUVer;
135}
136
137uint64_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(Value: CSKY::AEK_INVALID);
144}
145
146StringRef 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
153static bool stripNegationPrefix(StringRef &Name) {
154 if (Name.starts_with(Prefix: "no")) {
155 Name = Name.substr(Start: 2);
156 return true;
157 }
158 return false;
159}
160
161StringRef CSKY::getArchExtFeature(StringRef ArchExt) {
162 bool Negated = stripNegationPrefix(Name&: 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
171bool 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(x: AE.Feature);
179 }
180
181 return true;
182}
183