1 | //===-- unittests/RISCVISAInfoTest.cpp ------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/TargetParser/RISCVISAInfo.h" |
10 | #include "llvm/ADT/StringMap.h" |
11 | #include "llvm/Testing/Support/Error.h" |
12 | #include "gtest/gtest.h" |
13 | |
14 | using ::testing::ElementsAre; |
15 | |
16 | using namespace llvm; |
17 | |
18 | bool operator==(const RISCVISAUtils::ExtensionVersion &A, |
19 | const RISCVISAUtils::ExtensionVersion &B) { |
20 | return A.Major == B.Major && A.Minor == B.Minor; |
21 | } |
22 | |
23 | TEST(ParseNormalizedArchString, RejectsUpperCase) { |
24 | for (StringRef Input : {"RV32" , "rV64" , "rv32i2P0" , "rv64i2p0_A2p0" }) { |
25 | EXPECT_EQ( |
26 | toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()), |
27 | "string must be lowercase" ); |
28 | } |
29 | } |
30 | |
31 | TEST(ParseNormalizedArchString, RejectsInvalidBaseISA) { |
32 | for (StringRef Input : {"rv32" , "rv64" , "rv32j" , "rv65i" }) { |
33 | EXPECT_EQ( |
34 | toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()), |
35 | "arch string must begin with valid base ISA" ); |
36 | } |
37 | } |
38 | |
39 | TEST(ParseNormalizedArchString, RejectsMalformedInputs) { |
40 | for (StringRef Input : {"rv64i2p0_" , "rv32i2p0__a2p0" , "rv32e2.0" , "rv64e2p" , |
41 | "rv32i" , "rv64ip1" }) { |
42 | EXPECT_EQ( |
43 | toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()), |
44 | "extension lacks version in expected format" ); |
45 | } |
46 | } |
47 | |
48 | TEST(ParseNormalizedArchString, AcceptsValidBaseISAsAndSetsXLen) { |
49 | auto MaybeRV32I = RISCVISAInfo::parseNormalizedArchString(Arch: "rv32i2p0" ); |
50 | ASSERT_THAT_EXPECTED(MaybeRV32I, Succeeded()); |
51 | RISCVISAInfo &InfoRV32I = **MaybeRV32I; |
52 | EXPECT_EQ(InfoRV32I.getExtensions().size(), 1UL); |
53 | EXPECT_TRUE(InfoRV32I.getExtensions().at("i" ) == |
54 | (RISCVISAUtils::ExtensionVersion{2, 0})); |
55 | EXPECT_EQ(InfoRV32I.getXLen(), 32U); |
56 | |
57 | auto MaybeRV32E = RISCVISAInfo::parseNormalizedArchString(Arch: "rv32e2p0" ); |
58 | ASSERT_THAT_EXPECTED(MaybeRV32E, Succeeded()); |
59 | RISCVISAInfo &InfoRV32E = **MaybeRV32E; |
60 | EXPECT_EQ(InfoRV32E.getExtensions().size(), 1UL); |
61 | EXPECT_TRUE(InfoRV32E.getExtensions().at("e" ) == |
62 | (RISCVISAUtils::ExtensionVersion{2, 0})); |
63 | EXPECT_EQ(InfoRV32E.getXLen(), 32U); |
64 | |
65 | auto MaybeRV64I = RISCVISAInfo::parseNormalizedArchString(Arch: "rv64i2p0" ); |
66 | ASSERT_THAT_EXPECTED(MaybeRV64I, Succeeded()); |
67 | RISCVISAInfo &InfoRV64I = **MaybeRV64I; |
68 | EXPECT_EQ(InfoRV64I.getExtensions().size(), 1UL); |
69 | EXPECT_TRUE(InfoRV64I.getExtensions().at("i" ) == |
70 | (RISCVISAUtils::ExtensionVersion{2, 0})); |
71 | EXPECT_EQ(InfoRV64I.getXLen(), 64U); |
72 | |
73 | auto MaybeRV64E = RISCVISAInfo::parseNormalizedArchString(Arch: "rv64e2p0" ); |
74 | ASSERT_THAT_EXPECTED(MaybeRV64E, Succeeded()); |
75 | RISCVISAInfo &InfoRV64E = **MaybeRV64E; |
76 | EXPECT_EQ(InfoRV64E.getExtensions().size(), 1UL); |
77 | EXPECT_TRUE(InfoRV64E.getExtensions().at("e" ) == |
78 | (RISCVISAUtils::ExtensionVersion{2, 0})); |
79 | EXPECT_EQ(InfoRV64E.getXLen(), 64U); |
80 | } |
81 | |
82 | TEST(ParseNormalizedArchString, AcceptsArbitraryExtensionsAndVersions) { |
83 | auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString( |
84 | Arch: "rv64i5p1_m3p2_zmadeup11p12_sfoo2p0_xbar3p0" ); |
85 | ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); |
86 | RISCVISAInfo &Info = **MaybeISAInfo; |
87 | EXPECT_EQ(Info.getExtensions().size(), 5UL); |
88 | EXPECT_TRUE(Info.getExtensions().at("i" ) == |
89 | (RISCVISAUtils::ExtensionVersion{5, 1})); |
90 | EXPECT_TRUE(Info.getExtensions().at("m" ) == |
91 | (RISCVISAUtils::ExtensionVersion{3, 2})); |
92 | EXPECT_TRUE(Info.getExtensions().at("zmadeup" ) == |
93 | (RISCVISAUtils::ExtensionVersion{11, 12})); |
94 | EXPECT_TRUE(Info.getExtensions().at("sfoo" ) == |
95 | (RISCVISAUtils::ExtensionVersion{2, 0})); |
96 | EXPECT_TRUE(Info.getExtensions().at("xbar" ) == |
97 | (RISCVISAUtils::ExtensionVersion{3, 0})); |
98 | } |
99 | |
100 | TEST(ParseNormalizedArchString, UpdatesFLenMinVLenMaxELen) { |
101 | auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString( |
102 | Arch: "rv64i2p0_d2p0_zvl64b1p0_zve64d1p0" ); |
103 | ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); |
104 | RISCVISAInfo &Info = **MaybeISAInfo; |
105 | EXPECT_EQ(Info.getXLen(), 64U); |
106 | EXPECT_EQ(Info.getFLen(), 64U); |
107 | EXPECT_EQ(Info.getMinVLen(), 64U); |
108 | EXPECT_EQ(Info.getMaxELen(), 64U); |
109 | } |
110 | |
111 | TEST(ParseArchString, RejectsUpperCase) { |
112 | for (StringRef Input : {"RV32" , "rV64" , "rv32i2P0" , "rv64i2p0_A2p0" }) { |
113 | EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), |
114 | "string must be lowercase" ); |
115 | } |
116 | } |
117 | |
118 | TEST(ParseArchString, RejectsInvalidBaseISA) { |
119 | for (StringRef Input : {"rv32" , "rv64" , "rv65i" }) { |
120 | EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), |
121 | "string must begin with rv32{i,e,g} or rv64{i,e,g}" ); |
122 | } |
123 | for (StringRef Input : {"rv32j" , "rv64k" , "rv32_i" }) { |
124 | EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), |
125 | "first letter should be 'e', 'i' or 'g'" ); |
126 | } |
127 | } |
128 | |
129 | TEST(ParseArchString, RejectsUnsupportedBaseISA) { |
130 | for (StringRef Input : {"rv128i" , "rv128g" }) { |
131 | EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), |
132 | "string must begin with rv32{i,e,g} or rv64{i,e,g}" ); |
133 | } |
134 | } |
135 | |
136 | TEST(ParseArchString, AcceptsSupportedBaseISAsAndSetsXLenAndFLen) { |
137 | auto MaybeRV32I = RISCVISAInfo::parseArchString(Arch: "rv32i" , EnableExperimentalExtension: true); |
138 | ASSERT_THAT_EXPECTED(MaybeRV32I, Succeeded()); |
139 | RISCVISAInfo &InfoRV32I = **MaybeRV32I; |
140 | RISCVISAInfo::OrderedExtensionMap ExtsRV32I = InfoRV32I.getExtensions(); |
141 | EXPECT_EQ(ExtsRV32I.size(), 1UL); |
142 | EXPECT_TRUE(ExtsRV32I.at("i" ) == (RISCVISAUtils::ExtensionVersion{2, 1})); |
143 | EXPECT_EQ(InfoRV32I.getXLen(), 32U); |
144 | EXPECT_EQ(InfoRV32I.getFLen(), 0U); |
145 | |
146 | auto MaybeRV32E = RISCVISAInfo::parseArchString(Arch: "rv32e" , EnableExperimentalExtension: true); |
147 | ASSERT_THAT_EXPECTED(MaybeRV32E, Succeeded()); |
148 | RISCVISAInfo &InfoRV32E = **MaybeRV32E; |
149 | RISCVISAInfo::OrderedExtensionMap ExtsRV32E = InfoRV32E.getExtensions(); |
150 | EXPECT_EQ(ExtsRV32E.size(), 1UL); |
151 | EXPECT_TRUE(ExtsRV32E.at("e" ) == (RISCVISAUtils::ExtensionVersion{2, 0})); |
152 | EXPECT_EQ(InfoRV32E.getXLen(), 32U); |
153 | EXPECT_EQ(InfoRV32E.getFLen(), 0U); |
154 | |
155 | auto MaybeRV32G = RISCVISAInfo::parseArchString(Arch: "rv32g" , EnableExperimentalExtension: true); |
156 | ASSERT_THAT_EXPECTED(MaybeRV32G, Succeeded()); |
157 | RISCVISAInfo &InfoRV32G = **MaybeRV32G; |
158 | RISCVISAInfo::OrderedExtensionMap ExtsRV32G = InfoRV32G.getExtensions(); |
159 | EXPECT_EQ(ExtsRV32G.size(), 7UL); |
160 | EXPECT_TRUE(ExtsRV32G.at("i" ) == (RISCVISAUtils::ExtensionVersion{2, 1})); |
161 | EXPECT_TRUE(ExtsRV32G.at("m" ) == (RISCVISAUtils::ExtensionVersion{2, 0})); |
162 | EXPECT_TRUE(ExtsRV32G.at("a" ) == (RISCVISAUtils::ExtensionVersion{2, 1})); |
163 | EXPECT_TRUE(ExtsRV32G.at("f" ) == (RISCVISAUtils::ExtensionVersion{2, 2})); |
164 | EXPECT_TRUE(ExtsRV32G.at("d" ) == (RISCVISAUtils::ExtensionVersion{2, 2})); |
165 | EXPECT_TRUE(ExtsRV32G.at("zicsr" ) == (RISCVISAUtils::ExtensionVersion{2, 0})); |
166 | EXPECT_TRUE(ExtsRV32G.at("zifencei" ) == |
167 | (RISCVISAUtils::ExtensionVersion{2, 0})); |
168 | EXPECT_EQ(InfoRV32G.getXLen(), 32U); |
169 | EXPECT_EQ(InfoRV32G.getFLen(), 64U); |
170 | |
171 | auto MaybeRV64I = RISCVISAInfo::parseArchString(Arch: "rv64i" , EnableExperimentalExtension: true); |
172 | ASSERT_THAT_EXPECTED(MaybeRV64I, Succeeded()); |
173 | RISCVISAInfo &InfoRV64I = **MaybeRV64I; |
174 | RISCVISAInfo::OrderedExtensionMap ExtsRV64I = InfoRV64I.getExtensions(); |
175 | EXPECT_EQ(ExtsRV64I.size(), 1UL); |
176 | EXPECT_TRUE(ExtsRV64I.at("i" ) == (RISCVISAUtils::ExtensionVersion{2, 1})); |
177 | EXPECT_EQ(InfoRV64I.getXLen(), 64U); |
178 | EXPECT_EQ(InfoRV64I.getFLen(), 0U); |
179 | |
180 | auto MaybeRV64E = RISCVISAInfo::parseArchString(Arch: "rv64e" , EnableExperimentalExtension: true); |
181 | ASSERT_THAT_EXPECTED(MaybeRV64E, Succeeded()); |
182 | RISCVISAInfo &InfoRV64E = **MaybeRV64E; |
183 | RISCVISAInfo::OrderedExtensionMap ExtsRV64E = InfoRV64E.getExtensions(); |
184 | EXPECT_EQ(ExtsRV64E.size(), 1UL); |
185 | EXPECT_TRUE(ExtsRV64E.at("e" ) == (RISCVISAUtils::ExtensionVersion{2, 0})); |
186 | EXPECT_EQ(InfoRV64E.getXLen(), 64U); |
187 | EXPECT_EQ(InfoRV64E.getFLen(), 0U); |
188 | |
189 | auto MaybeRV64G = RISCVISAInfo::parseArchString(Arch: "rv64g" , EnableExperimentalExtension: true); |
190 | ASSERT_THAT_EXPECTED(MaybeRV64G, Succeeded()); |
191 | RISCVISAInfo &InfoRV64G = **MaybeRV64G; |
192 | RISCVISAInfo::OrderedExtensionMap ExtsRV64G = InfoRV64G.getExtensions(); |
193 | EXPECT_EQ(ExtsRV64G.size(), 7UL); |
194 | EXPECT_TRUE(ExtsRV64G.at("i" ) == (RISCVISAUtils::ExtensionVersion{2, 1})); |
195 | EXPECT_TRUE(ExtsRV64G.at("m" ) == (RISCVISAUtils::ExtensionVersion{2, 0})); |
196 | EXPECT_TRUE(ExtsRV64G.at("a" ) == (RISCVISAUtils::ExtensionVersion{2, 1})); |
197 | EXPECT_TRUE(ExtsRV64G.at("f" ) == (RISCVISAUtils::ExtensionVersion{2, 2})); |
198 | EXPECT_TRUE(ExtsRV64G.at("d" ) == (RISCVISAUtils::ExtensionVersion{2, 2})); |
199 | EXPECT_TRUE(ExtsRV64G.at("zicsr" ) == (RISCVISAUtils::ExtensionVersion{2, 0})); |
200 | EXPECT_TRUE(ExtsRV64G.at("zifencei" ) == |
201 | (RISCVISAUtils::ExtensionVersion{2, 0})); |
202 | EXPECT_EQ(InfoRV64G.getXLen(), 64U); |
203 | EXPECT_EQ(InfoRV64G.getFLen(), 64U); |
204 | } |
205 | |
206 | TEST(ParseArchString, RejectsUnrecognizedExtensionNamesByDefault) { |
207 | EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv64ib" , true).takeError()), |
208 | "unsupported standard user-level extension 'b'" ); |
209 | EXPECT_EQ( |
210 | toString( |
211 | RISCVISAInfo::parseArchString("rv32i_zmadeup" , true).takeError()), |
212 | "unsupported standard user-level extension 'zmadeup'" ); |
213 | EXPECT_EQ( |
214 | toString( |
215 | RISCVISAInfo::parseArchString("rv64g_smadeup" , true).takeError()), |
216 | "unsupported standard supervisor-level extension 'smadeup'" ); |
217 | EXPECT_EQ( |
218 | toString( |
219 | RISCVISAInfo::parseArchString("rv64g_xmadeup" , true).takeError()), |
220 | "unsupported non-standard user-level extension 'xmadeup'" ); |
221 | EXPECT_EQ( |
222 | toString(RISCVISAInfo::parseArchString("rv64ib1p0" , true).takeError()), |
223 | "unsupported standard user-level extension 'b'" ); |
224 | EXPECT_EQ( |
225 | toString( |
226 | RISCVISAInfo::parseArchString("rv32i_zmadeup1p0" , true).takeError()), |
227 | "unsupported standard user-level extension 'zmadeup'" ); |
228 | EXPECT_EQ( |
229 | toString( |
230 | RISCVISAInfo::parseArchString("rv64g_smadeup1p0" , true).takeError()), |
231 | "unsupported standard supervisor-level extension 'smadeup'" ); |
232 | EXPECT_EQ( |
233 | toString( |
234 | RISCVISAInfo::parseArchString("rv64g_xmadeup1p0" , true).takeError()), |
235 | "unsupported non-standard user-level extension 'xmadeup'" ); |
236 | } |
237 | |
238 | TEST(ParseArchString, IgnoresUnrecognizedExtensionNamesWithIgnoreUnknown) { |
239 | for (StringRef Input : {"rv32ib" , "rv32i_zmadeup" , |
240 | "rv64i_smadeup" , "rv64i_xmadeup" }) { |
241 | auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true, ExperimentalExtensionVersionCheck: false, IgnoreUnknown: true); |
242 | ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); |
243 | RISCVISAInfo &Info = **MaybeISAInfo; |
244 | RISCVISAInfo::OrderedExtensionMap Exts = Info.getExtensions(); |
245 | EXPECT_EQ(Exts.size(), 1UL); |
246 | EXPECT_TRUE(Exts.at("i" ) == (RISCVISAUtils::ExtensionVersion{2, 1})); |
247 | } |
248 | |
249 | // Checks that supported extensions aren't incorrectly ignored when a |
250 | // version is present (an early version of the patch had this mistake). |
251 | auto MaybeISAInfo = |
252 | RISCVISAInfo::parseArchString(Arch: "rv32i_zbc1p0_xmadeup" , EnableExperimentalExtension: true, ExperimentalExtensionVersionCheck: false, IgnoreUnknown: true); |
253 | ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); |
254 | RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); |
255 | EXPECT_TRUE(Exts.at("zbc" ) == (RISCVISAUtils::ExtensionVersion{1, 0})); |
256 | } |
257 | |
258 | TEST(ParseArchString, AcceptsVersionInLongOrShortForm) { |
259 | for (StringRef Input : {"rv64i2p1" }) { |
260 | auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true); |
261 | ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); |
262 | RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); |
263 | EXPECT_TRUE(Exts.at("i" ) == (RISCVISAUtils::ExtensionVersion{2, 1})); |
264 | } |
265 | for (StringRef Input : {"rv32i_zfinx1" , "rv32i_zfinx1p0" }) { |
266 | auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true); |
267 | ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); |
268 | RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); |
269 | EXPECT_TRUE(Exts.at("zfinx" ) == (RISCVISAUtils::ExtensionVersion{1, 0})); |
270 | } |
271 | } |
272 | |
273 | TEST(ParseArchString, RejectsUnrecognizedExtensionVersionsByDefault) { |
274 | EXPECT_EQ( |
275 | toString(RISCVISAInfo::parseArchString("rv64i2p" , true).takeError()), |
276 | "minor version number missing after 'p' for extension 'i'" ); |
277 | EXPECT_EQ( |
278 | toString(RISCVISAInfo::parseArchString("rv64i1p0" , true).takeError()), |
279 | "unsupported version number 1.0 for extension 'i'" ); |
280 | EXPECT_EQ( |
281 | toString(RISCVISAInfo::parseArchString("rv64i9p9" , true).takeError()), |
282 | "unsupported version number 9.9 for extension 'i'" ); |
283 | EXPECT_EQ( |
284 | toString(RISCVISAInfo::parseArchString("rv32im0p1" , true).takeError()), |
285 | "unsupported version number 0.1 for extension 'm'" ); |
286 | EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv32izifencei10p10" , true) |
287 | .takeError()), |
288 | "unsupported version number 10.10 for extension 'zifencei'" ); |
289 | } |
290 | |
291 | TEST(ParseArchString, |
292 | UsesDefaultVersionForUnrecognisedBaseISAVersionWithIgnoreUnknown) { |
293 | for (StringRef Input : {"rv32i0p1" , "rv32i99p99" , "rv64i0p1" , "rv64i99p99" }) { |
294 | auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true, ExperimentalExtensionVersionCheck: false, IgnoreUnknown: true); |
295 | ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); |
296 | RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); |
297 | EXPECT_EQ(Exts.size(), 1UL); |
298 | EXPECT_TRUE(Exts.at("i" ) == (RISCVISAUtils::ExtensionVersion{2, 1})); |
299 | } |
300 | for (StringRef Input : {"rv32e0p1" , "rv32e99p99" , "rv64e0p1" , "rv64e99p99" }) { |
301 | auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true, ExperimentalExtensionVersionCheck: false, IgnoreUnknown: true); |
302 | ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); |
303 | RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); |
304 | EXPECT_EQ(Exts.size(), 1UL); |
305 | EXPECT_TRUE(Exts.at("e" ) == (RISCVISAUtils::ExtensionVersion{2, 0})); |
306 | } |
307 | } |
308 | |
309 | TEST(ParseArchString, |
310 | IgnoresExtensionsWithUnrecognizedVersionsWithIgnoreUnknown) { |
311 | for (StringRef Input : {"rv32im1p1" , "rv64i_svnapot10p9" , "rv32i_zicsr0p5" }) { |
312 | auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true, ExperimentalExtensionVersionCheck: false, IgnoreUnknown: true); |
313 | ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); |
314 | RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); |
315 | EXPECT_EQ(Exts.size(), 1UL); |
316 | EXPECT_TRUE(Exts.at("i" ) == (RISCVISAUtils::ExtensionVersion{2, 1})); |
317 | } |
318 | } |
319 | |
320 | TEST(ParseArchString, AcceptsUnderscoreSplittingExtensions) { |
321 | for (StringRef Input : {"rv32imafdczifencei" , "rv32i_m_a_f_d_c_zifencei" }) { |
322 | auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true); |
323 | ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); |
324 | RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); |
325 | EXPECT_EQ(Exts.size(), 8UL); |
326 | EXPECT_EQ(Exts.count("i" ), 1U); |
327 | EXPECT_EQ(Exts.count("m" ), 1U); |
328 | EXPECT_EQ(Exts.count("a" ), 1U); |
329 | EXPECT_EQ(Exts.count("f" ), 1U); |
330 | EXPECT_EQ(Exts.count("d" ), 1U); |
331 | EXPECT_EQ(Exts.count("c" ), 1U); |
332 | EXPECT_EQ(Exts.count("zicsr" ), 1U); |
333 | EXPECT_EQ(Exts.count("zifencei" ), 1U); |
334 | } |
335 | } |
336 | |
337 | TEST(ParseArchString, AcceptsRelaxSingleLetterExtensions) { |
338 | for (StringRef Input : |
339 | {"rv32imfad" , "rv32im_fa_d" , "rv32im2p0fad" , "rv32i2p1m2p0fad" }) { |
340 | auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true); |
341 | ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); |
342 | RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); |
343 | EXPECT_EQ(Exts.size(), 6UL); |
344 | EXPECT_EQ(Exts.count("i" ), 1U); |
345 | EXPECT_EQ(Exts.count("m" ), 1U); |
346 | EXPECT_EQ(Exts.count("f" ), 1U); |
347 | EXPECT_EQ(Exts.count("a" ), 1U); |
348 | EXPECT_EQ(Exts.count("d" ), 1U); |
349 | EXPECT_EQ(Exts.count("zicsr" ), 1U); |
350 | } |
351 | } |
352 | |
353 | TEST(ParseArchString, AcceptsRelaxMixedLetterExtensions) { |
354 | for (StringRef Input : |
355 | {"rv32i_zihintntl_m_a_f_d_svinval" , "rv32izihintntl_mafdsvinval" , |
356 | "rv32i_zihintntl_mafd_svinval" }) { |
357 | auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true); |
358 | ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); |
359 | RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); |
360 | EXPECT_EQ(Exts.size(), 8UL); |
361 | EXPECT_EQ(Exts.count("i" ), 1U); |
362 | EXPECT_EQ(Exts.count("m" ), 1U); |
363 | EXPECT_EQ(Exts.count("a" ), 1U); |
364 | EXPECT_EQ(Exts.count("f" ), 1U); |
365 | EXPECT_EQ(Exts.count("d" ), 1U); |
366 | EXPECT_EQ(Exts.count("zihintntl" ), 1U); |
367 | EXPECT_EQ(Exts.count("svinval" ), 1U); |
368 | EXPECT_EQ(Exts.count("zicsr" ), 1U); |
369 | } |
370 | } |
371 | |
372 | TEST(ParseArchString, AcceptsAmbiguousFromRelaxExtensions) { |
373 | for (StringRef Input : {"rv32i_zba_m" , "rv32izba_m" , "rv32izba1p0_m2p0" }) { |
374 | auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true); |
375 | ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); |
376 | RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); |
377 | EXPECT_EQ(Exts.size(), 3UL); |
378 | EXPECT_EQ(Exts.count("i" ), 1U); |
379 | EXPECT_EQ(Exts.count("zba" ), 1U); |
380 | EXPECT_EQ(Exts.count("m" ), 1U); |
381 | } |
382 | for (StringRef Input : |
383 | {"rv32ia_zba_m" , "rv32iazba_m" , "rv32ia2p1zba1p0_m2p0" }) { |
384 | auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true); |
385 | ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); |
386 | RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); |
387 | EXPECT_EQ(Exts.size(), 4UL); |
388 | EXPECT_EQ(Exts.count("i" ), 1U); |
389 | EXPECT_EQ(Exts.count("zba" ), 1U); |
390 | EXPECT_EQ(Exts.count("m" ), 1U); |
391 | EXPECT_EQ(Exts.count("a" ), 1U); |
392 | } |
393 | } |
394 | |
395 | TEST(ParseArchString, RejectsRelaxExtensionsNotStartWithEorIorG) { |
396 | EXPECT_EQ( |
397 | toString(RISCVISAInfo::parseArchString("rv32zba_im" , true).takeError()), |
398 | "first letter should be 'e', 'i' or 'g'" ); |
399 | } |
400 | |
401 | TEST(ParseArchString, |
402 | RejectsMultiLetterExtensionFollowBySingleLetterExtensions) { |
403 | for (StringRef Input : {"rv32izbam" , "rv32i_zbam" }) |
404 | EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), |
405 | "unsupported standard user-level extension 'zbam'" ); |
406 | EXPECT_EQ( |
407 | toString(RISCVISAInfo::parseArchString("rv32izbai_m" , true).takeError()), |
408 | "unsupported standard user-level extension 'zbai'" ); |
409 | EXPECT_EQ( |
410 | toString(RISCVISAInfo::parseArchString("rv32izbaim" , true).takeError()), |
411 | "unsupported standard user-level extension 'zbaim'" ); |
412 | EXPECT_EQ( |
413 | toString( |
414 | RISCVISAInfo::parseArchString("rv32i_zba1p0m" , true).takeError()), |
415 | "unsupported standard user-level extension 'zba1p0m'" ); |
416 | } |
417 | |
418 | TEST(ParseArchString, RejectsDoubleOrTrailingUnderscore) { |
419 | EXPECT_EQ( |
420 | toString(RISCVISAInfo::parseArchString("rv64i__m" , true).takeError()), |
421 | "extension name missing after separator '_'" ); |
422 | |
423 | for (StringRef Input : |
424 | {"rv32ezicsr__zifencei" , "rv32i_" , "rv32izicsr_" , "rv64im_" }) { |
425 | EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), |
426 | "extension name missing after separator '_'" ); |
427 | } |
428 | } |
429 | |
430 | TEST(ParseArchString, RejectsDuplicateExtensionNames) { |
431 | EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv64ii" , true).takeError()), |
432 | "invalid standard user-level extension 'i'" ); |
433 | EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv32ee" , true).takeError()), |
434 | "invalid standard user-level extension 'e'" ); |
435 | EXPECT_EQ( |
436 | toString(RISCVISAInfo::parseArchString("rv64imm" , true).takeError()), |
437 | "duplicated standard user-level extension 'm'" ); |
438 | EXPECT_EQ( |
439 | toString( |
440 | RISCVISAInfo::parseArchString("rv32i_zicsr_zicsr" , true).takeError()), |
441 | "duplicated standard user-level extension 'zicsr'" ); |
442 | } |
443 | |
444 | TEST(ParseArchString, |
445 | RejectsExperimentalExtensionsIfNotEnableExperimentalExtension) { |
446 | EXPECT_EQ( |
447 | toString(RISCVISAInfo::parseArchString("rv64iztso" , false).takeError()), |
448 | "requires '-menable-experimental-extensions' for experimental extension " |
449 | "'ztso'" ); |
450 | } |
451 | |
452 | TEST(ParseArchString, |
453 | AcceptsExperimentalExtensionsIfEnableExperimentalExtension) { |
454 | // Note: If ztso becomes none-experimental, this test will need |
455 | // updating (and unfortunately, it will still pass). The failure of |
456 | // RejectsExperimentalExtensionsIfNotEnableExperimentalExtension will |
457 | // hopefully serve as a reminder to update. |
458 | auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: "rv64iztso" , EnableExperimentalExtension: true, ExperimentalExtensionVersionCheck: false); |
459 | ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); |
460 | RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); |
461 | EXPECT_EQ(Exts.size(), 2UL); |
462 | EXPECT_EQ(Exts.count("ztso" ), 1U); |
463 | auto MaybeISAInfo2 = RISCVISAInfo::parseArchString(Arch: "rv64iztso0p1" , EnableExperimentalExtension: true); |
464 | ASSERT_THAT_EXPECTED(MaybeISAInfo2, Succeeded()); |
465 | RISCVISAInfo::OrderedExtensionMap Exts2 = (*MaybeISAInfo2)->getExtensions(); |
466 | EXPECT_EQ(Exts2.size(), 2UL); |
467 | EXPECT_EQ(Exts2.count("ztso" ), 1U); |
468 | } |
469 | |
470 | TEST(ParseArchString, |
471 | RequiresExplicitVersionNumberForExperimentalExtensionByDefault) { |
472 | EXPECT_EQ( |
473 | toString(RISCVISAInfo::parseArchString("rv64iztso" , true).takeError()), |
474 | "experimental extension requires explicit version number `ztso`" ); |
475 | } |
476 | |
477 | TEST(ParseArchString, |
478 | AcceptsUnrecognizedVersionIfNotExperimentalExtensionVersionCheck) { |
479 | auto MaybeISAInfo = |
480 | RISCVISAInfo::parseArchString(Arch: "rv64iztso9p9" , EnableExperimentalExtension: true, ExperimentalExtensionVersionCheck: false); |
481 | ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); |
482 | RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); |
483 | EXPECT_EQ(Exts.size(), 2UL); |
484 | EXPECT_TRUE(Exts.at("ztso" ) == (RISCVISAUtils::ExtensionVersion{9, 9})); |
485 | } |
486 | |
487 | TEST(ParseArchString, RejectsUnrecognizedVersionForExperimentalExtension) { |
488 | EXPECT_EQ( |
489 | toString(RISCVISAInfo::parseArchString("rv64iztso9p9" , true).takeError()), |
490 | "unsupported version number 9.9 for experimental extension 'ztso' " |
491 | "(this compiler supports 0.1)" ); |
492 | } |
493 | |
494 | TEST(ParseArchString, RejectsExtensionVersionForG) { |
495 | for (StringRef Input : {"rv32g1c" , "rv64g2p0" }) { |
496 | EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), |
497 | "version not supported for 'g'" ); |
498 | } |
499 | } |
500 | |
501 | TEST(ParseArchString, AddsImpliedExtensions) { |
502 | // Does not attempt to exhaustively test all implications. |
503 | auto MaybeRV64ID = RISCVISAInfo::parseArchString(Arch: "rv64id" , EnableExperimentalExtension: true); |
504 | ASSERT_THAT_EXPECTED(MaybeRV64ID, Succeeded()); |
505 | RISCVISAInfo::OrderedExtensionMap ExtsRV64ID = |
506 | (*MaybeRV64ID)->getExtensions(); |
507 | EXPECT_EQ(ExtsRV64ID.size(), 4UL); |
508 | EXPECT_EQ(ExtsRV64ID.count("i" ), 1U); |
509 | EXPECT_EQ(ExtsRV64ID.count("f" ), 1U); |
510 | EXPECT_EQ(ExtsRV64ID.count("d" ), 1U); |
511 | EXPECT_EQ(ExtsRV64ID.count("zicsr" ), 1U); |
512 | |
513 | auto MaybeRV32IZKN = RISCVISAInfo::parseArchString(Arch: "rv64izkn" , EnableExperimentalExtension: true); |
514 | ASSERT_THAT_EXPECTED(MaybeRV32IZKN, Succeeded()); |
515 | RISCVISAInfo::OrderedExtensionMap ExtsRV32IZKN = |
516 | (*MaybeRV32IZKN)->getExtensions(); |
517 | EXPECT_EQ(ExtsRV32IZKN.size(), 8UL); |
518 | EXPECT_EQ(ExtsRV32IZKN.count("i" ), 1U); |
519 | EXPECT_EQ(ExtsRV32IZKN.count("zbkb" ), 1U); |
520 | EXPECT_EQ(ExtsRV32IZKN.count("zbkc" ), 1U); |
521 | EXPECT_EQ(ExtsRV32IZKN.count("zbkx" ), 1U); |
522 | EXPECT_EQ(ExtsRV32IZKN.count("zkne" ), 1U); |
523 | EXPECT_EQ(ExtsRV32IZKN.count("zknd" ), 1U); |
524 | EXPECT_EQ(ExtsRV32IZKN.count("zknh" ), 1U); |
525 | EXPECT_EQ(ExtsRV32IZKN.count("zkn" ), 1U); |
526 | } |
527 | |
528 | TEST(ParseArchString, RejectsConflictingExtensions) { |
529 | for (StringRef Input : {"rv32ifzfinx" , "rv64gzdinx" }) { |
530 | EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), |
531 | "'f' and 'zfinx' extensions are incompatible" ); |
532 | } |
533 | |
534 | for (StringRef Input : {"rv32idc_zcmp1p0" , "rv64idc_zcmp1p0" }) { |
535 | EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), |
536 | "'zcmp' extension is incompatible with 'c' extension when 'd' " |
537 | "extension is enabled" ); |
538 | } |
539 | |
540 | for (StringRef Input : {"rv32id_zcd1p0_zcmp1p0" , "rv64id_zcd1p0_zcmp1p0" }) { |
541 | EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), |
542 | "'zcmp' extension is incompatible with 'zcd' extension when 'd' " |
543 | "extension is enabled" ); |
544 | } |
545 | |
546 | for (StringRef Input : {"rv32idc_zcmt1p0" , "rv64idc_zcmt1p0" }) { |
547 | EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), |
548 | "'zcmt' extension is incompatible with 'c' extension when 'd' " |
549 | "extension is enabled" ); |
550 | } |
551 | |
552 | for (StringRef Input : {"rv32id_zcd1p0_zcmt1p0" , "rv64id_zcd1p0_zcmt1p0" }) { |
553 | EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), |
554 | "'zcmt' extension is incompatible with 'zcd' extension when 'd' " |
555 | "extension is enabled" ); |
556 | } |
557 | |
558 | for (StringRef Input : {"rv64if_zcf" }) { |
559 | EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), |
560 | "'zcf' is only supported for 'rv32'" ); |
561 | } |
562 | } |
563 | |
564 | TEST(ToFeatures, IIsDroppedAndExperimentalExtensionsArePrefixed) { |
565 | auto MaybeISAInfo1 = |
566 | RISCVISAInfo::parseArchString(Arch: "rv64im_ztso" , EnableExperimentalExtension: true, ExperimentalExtensionVersionCheck: false); |
567 | ASSERT_THAT_EXPECTED(MaybeISAInfo1, Succeeded()); |
568 | EXPECT_THAT((*MaybeISAInfo1)->toFeatures(), |
569 | ElementsAre("+m" , "+experimental-ztso" )); |
570 | |
571 | auto MaybeISAInfo2 = |
572 | RISCVISAInfo::parseArchString(Arch: "rv32e_ztso_xventanacondops" , EnableExperimentalExtension: true, ExperimentalExtensionVersionCheck: false); |
573 | ASSERT_THAT_EXPECTED(MaybeISAInfo2, Succeeded()); |
574 | EXPECT_THAT((*MaybeISAInfo2)->toFeatures(), |
575 | ElementsAre("+e" , "+experimental-ztso" , "+xventanacondops" )); |
576 | } |
577 | |
578 | TEST(ToFeatures, UnsupportedExtensionsAreDropped) { |
579 | auto MaybeISAInfo = |
580 | RISCVISAInfo::parseNormalizedArchString(Arch: "rv64i2p0_m2p0_xmadeup1p0" ); |
581 | ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); |
582 | EXPECT_THAT((*MaybeISAInfo)->toFeatures(), ElementsAre("+m" )); |
583 | } |
584 | |
585 | TEST(ToFeatures, UnsupportedExtensionsAreKeptIfIgnoreUnknownIsFalse) { |
586 | auto MaybeISAInfo = |
587 | RISCVISAInfo::parseNormalizedArchString(Arch: "rv64i2p0_m2p0_xmadeup1p0" ); |
588 | ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); |
589 | EXPECT_THAT((*MaybeISAInfo)->toFeatures(false, false), |
590 | ElementsAre("+m" , "+xmadeup" )); |
591 | } |
592 | |
593 | TEST(ToFeatures, AddAllExtensionsAddsNegativeExtensions) { |
594 | auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString(Arch: "rv64i2p0_m2p0" ); |
595 | ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); |
596 | |
597 | auto Features = (*MaybeISAInfo)->toFeatures(AddAllExtensions: true); |
598 | EXPECT_GT(Features.size(), 1UL); |
599 | EXPECT_EQ(Features.front(), "+m" ); |
600 | // Every feature after should be a negative feature |
601 | for (auto &NegativeExt : llvm::drop_begin(RangeOrContainer&: Features)) |
602 | EXPECT_TRUE(NegativeExt.substr(0, 1) == "-" ); |
603 | } |
604 | |
605 | TEST(OrderedExtensionMap, ExtensionsAreCorrectlyOrdered) { |
606 | RISCVISAInfo::OrderedExtensionMap Exts; |
607 | for (auto ExtName : {"y" , "l" , "m" , "c" , "i" , "xfoo" , "xbar" , "sfoo" , "sbar" , |
608 | "zmfoo" , "zzfoo" , "zfinx" , "zicsr" }) |
609 | Exts[ExtName] = {.Major: 1, .Minor: 0}; |
610 | |
611 | std::vector<std::string> ExtNames; |
612 | for (const auto &Ext : Exts) |
613 | ExtNames.push_back(x: Ext.first); |
614 | |
615 | // FIXME: 'l' and 'y' should be ordered after 'i', 'm', 'c'. |
616 | EXPECT_THAT(ExtNames, |
617 | ElementsAre("i" , "m" , "l" , "c" , "y" , "zicsr" , "zmfoo" , "zfinx" , |
618 | "zzfoo" , "sbar" , "sfoo" , "xbar" , "xfoo" )); |
619 | } |
620 | |
621 | TEST(ParseArchString, ZceImplication) { |
622 | auto MaybeRV32IZce = RISCVISAInfo::parseArchString(Arch: "rv32izce" , EnableExperimentalExtension: true); |
623 | ASSERT_THAT_EXPECTED(MaybeRV32IZce, Succeeded()); |
624 | RISCVISAInfo::OrderedExtensionMap ExtsRV32IZce = |
625 | (*MaybeRV32IZce)->getExtensions(); |
626 | EXPECT_EQ(ExtsRV32IZce.size(), 7UL); |
627 | EXPECT_EQ(ExtsRV32IZce.count("i" ), 1U); |
628 | EXPECT_EQ(ExtsRV32IZce.count("zicsr" ), 1U); |
629 | EXPECT_EQ(ExtsRV32IZce.count("zca" ), 1U); |
630 | EXPECT_EQ(ExtsRV32IZce.count("zcb" ), 1U); |
631 | EXPECT_EQ(ExtsRV32IZce.count("zce" ), 1U); |
632 | EXPECT_EQ(ExtsRV32IZce.count("zcmp" ), 1U); |
633 | EXPECT_EQ(ExtsRV32IZce.count("zcmt" ), 1U); |
634 | |
635 | auto MaybeRV32IFZce = RISCVISAInfo::parseArchString(Arch: "rv32ifzce" , EnableExperimentalExtension: true); |
636 | ASSERT_THAT_EXPECTED(MaybeRV32IFZce, Succeeded()); |
637 | RISCVISAInfo::OrderedExtensionMap ExtsRV32IFZce = |
638 | (*MaybeRV32IFZce)->getExtensions(); |
639 | EXPECT_EQ(ExtsRV32IFZce.size(), 9UL); |
640 | EXPECT_EQ(ExtsRV32IFZce.count("i" ), 1U); |
641 | EXPECT_EQ(ExtsRV32IFZce.count("zicsr" ), 1U); |
642 | EXPECT_EQ(ExtsRV32IFZce.count("f" ), 1U); |
643 | EXPECT_EQ(ExtsRV32IFZce.count("zca" ), 1U); |
644 | EXPECT_EQ(ExtsRV32IFZce.count("zcb" ), 1U); |
645 | EXPECT_EQ(ExtsRV32IFZce.count("zce" ), 1U); |
646 | EXPECT_EQ(ExtsRV32IFZce.count("zcf" ), 1U); |
647 | EXPECT_EQ(ExtsRV32IFZce.count("zcmp" ), 1U); |
648 | EXPECT_EQ(ExtsRV32IFZce.count("zcmt" ), 1U); |
649 | |
650 | auto MaybeRV32IDZce = RISCVISAInfo::parseArchString(Arch: "rv32idzce" , EnableExperimentalExtension: true); |
651 | ASSERT_THAT_EXPECTED(MaybeRV32IDZce, Succeeded()); |
652 | RISCVISAInfo::OrderedExtensionMap ExtsRV32IDZce = |
653 | (*MaybeRV32IDZce)->getExtensions(); |
654 | EXPECT_EQ(ExtsRV32IDZce.size(), 10UL); |
655 | EXPECT_EQ(ExtsRV32IDZce.count("i" ), 1U); |
656 | EXPECT_EQ(ExtsRV32IDZce.count("zicsr" ), 1U); |
657 | EXPECT_EQ(ExtsRV32IDZce.count("f" ), 1U); |
658 | EXPECT_EQ(ExtsRV32IDZce.count("d" ), 1U); |
659 | EXPECT_EQ(ExtsRV32IDZce.count("zca" ), 1U); |
660 | EXPECT_EQ(ExtsRV32IDZce.count("zcb" ), 1U); |
661 | EXPECT_EQ(ExtsRV32IDZce.count("zce" ), 1U); |
662 | EXPECT_EQ(ExtsRV32IDZce.count("zcf" ), 1U); |
663 | EXPECT_EQ(ExtsRV32IDZce.count("zcmp" ), 1U); |
664 | EXPECT_EQ(ExtsRV32IDZce.count("zcmt" ), 1U); |
665 | |
666 | auto MaybeRV64IZce = RISCVISAInfo::parseArchString(Arch: "rv64izce" , EnableExperimentalExtension: true); |
667 | ASSERT_THAT_EXPECTED(MaybeRV64IZce, Succeeded()); |
668 | RISCVISAInfo::OrderedExtensionMap ExtsRV64IZce = |
669 | (*MaybeRV64IZce)->getExtensions(); |
670 | EXPECT_EQ(ExtsRV64IZce.size(), 7UL); |
671 | EXPECT_EQ(ExtsRV64IZce.count("i" ), 1U); |
672 | EXPECT_EQ(ExtsRV64IZce.count("zicsr" ), 1U); |
673 | EXPECT_EQ(ExtsRV64IZce.count("zca" ), 1U); |
674 | EXPECT_EQ(ExtsRV64IZce.count("zcb" ), 1U); |
675 | EXPECT_EQ(ExtsRV64IZce.count("zce" ), 1U); |
676 | EXPECT_EQ(ExtsRV64IZce.count("zcmp" ), 1U); |
677 | EXPECT_EQ(ExtsRV64IZce.count("zcmt" ), 1U); |
678 | |
679 | auto MaybeRV64IFZce = RISCVISAInfo::parseArchString(Arch: "rv64ifzce" , EnableExperimentalExtension: true); |
680 | ASSERT_THAT_EXPECTED(MaybeRV64IFZce, Succeeded()); |
681 | RISCVISAInfo::OrderedExtensionMap ExtsRV64IFZce = |
682 | (*MaybeRV64IFZce)->getExtensions(); |
683 | EXPECT_EQ(ExtsRV64IFZce.size(), 8UL); |
684 | EXPECT_EQ(ExtsRV64IFZce.count("i" ), 1U); |
685 | EXPECT_EQ(ExtsRV64IFZce.count("zicsr" ), 1U); |
686 | EXPECT_EQ(ExtsRV64IFZce.count("f" ), 1U); |
687 | EXPECT_EQ(ExtsRV64IFZce.count("zca" ), 1U); |
688 | EXPECT_EQ(ExtsRV64IFZce.count("zcb" ), 1U); |
689 | EXPECT_EQ(ExtsRV64IFZce.count("zce" ), 1U); |
690 | EXPECT_EQ(ExtsRV64IFZce.count("zcmp" ), 1U); |
691 | EXPECT_EQ(ExtsRV64IFZce.count("zcmt" ), 1U); |
692 | |
693 | EXPECT_EQ(ExtsRV64IFZce.count("zca" ), 1U); |
694 | EXPECT_EQ(ExtsRV64IFZce.count("zcb" ), 1U); |
695 | EXPECT_EQ(ExtsRV64IFZce.count("zce" ), 1U); |
696 | EXPECT_EQ(ExtsRV64IFZce.count("zcmp" ), 1U); |
697 | EXPECT_EQ(ExtsRV64IFZce.count("zcmt" ), 1U); |
698 | |
699 | auto MaybeRV64IDZce = RISCVISAInfo::parseArchString(Arch: "rv64idzce" , EnableExperimentalExtension: true); |
700 | ASSERT_THAT_EXPECTED(MaybeRV64IDZce, Succeeded()); |
701 | RISCVISAInfo::OrderedExtensionMap ExtsRV64IDZce = |
702 | (*MaybeRV64IDZce)->getExtensions(); |
703 | EXPECT_EQ(ExtsRV64IDZce.size(), 9UL); |
704 | EXPECT_EQ(ExtsRV64IDZce.count("i" ), 1U); |
705 | EXPECT_EQ(ExtsRV64IDZce.count("zicsr" ), 1U); |
706 | EXPECT_EQ(ExtsRV64IDZce.count("f" ), 1U); |
707 | EXPECT_EQ(ExtsRV64IDZce.count("d" ), 1U); |
708 | EXPECT_EQ(ExtsRV64IDZce.count("zca" ), 1U); |
709 | EXPECT_EQ(ExtsRV64IDZce.count("zcb" ), 1U); |
710 | EXPECT_EQ(ExtsRV64IDZce.count("zce" ), 1U); |
711 | EXPECT_EQ(ExtsRV64IDZce.count("zcmp" ), 1U); |
712 | EXPECT_EQ(ExtsRV64IDZce.count("zcmt" ), 1U); |
713 | } |
714 | |
715 | TEST(isSupportedExtensionWithVersion, AcceptsSingleExtensionWithVersion) { |
716 | EXPECT_TRUE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb1p0" )); |
717 | EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb" )); |
718 | EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo1p0" )); |
719 | EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo" )); |
720 | EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("" )); |
721 | EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("c2p0zbb1p0" )); |
722 | } |
723 | |
724 | TEST(getTargetFeatureForExtension, RetrieveTargetFeatureFromOneExt) { |
725 | EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbb" ), "zbb" ); |
726 | EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso0p1" ), |
727 | "experimental-ztso" ); |
728 | EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso" ), |
729 | "experimental-ztso" ); |
730 | EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zihintntl1234p4321" ), |
731 | "" ); |
732 | EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zfoo" ), "" ); |
733 | EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("" ), "" ); |
734 | EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbbzihintntl" ), "" ); |
735 | } |
736 | |
737 | TEST(RiscvExtensionsHelp, CheckExtensions) { |
738 | // clang-format off |
739 | std::string ExpectedOutput = |
740 | R"(All available -march extensions for RISC-V |
741 | |
742 | Name Version Description |
743 | i 2.1 This is a long dummy description |
744 | e 2.0 |
745 | m 2.0 |
746 | a 2.1 |
747 | f 2.2 |
748 | d 2.2 |
749 | c 2.0 |
750 | v 1.0 |
751 | h 1.0 |
752 | zic64b 1.0 |
753 | zicbom 1.0 |
754 | zicbop 1.0 |
755 | zicboz 1.0 |
756 | ziccamoa 1.0 |
757 | ziccif 1.0 |
758 | zicclsm 1.0 |
759 | ziccrse 1.0 |
760 | zicntr 2.0 |
761 | zicond 1.0 |
762 | zicsr 2.0 |
763 | zifencei 2.0 |
764 | zihintntl 1.0 |
765 | zihintpause 2.0 |
766 | zihpm 2.0 |
767 | zimop 1.0 |
768 | zmmul 1.0 |
769 | za128rs 1.0 |
770 | za64rs 1.0 |
771 | zacas 1.0 |
772 | zama16b 1.0 |
773 | zawrs 1.0 |
774 | zfa 1.0 |
775 | zfh 1.0 |
776 | zfhmin 1.0 |
777 | zfinx 1.0 |
778 | zdinx 1.0 |
779 | zca 1.0 |
780 | zcb 1.0 |
781 | zcd 1.0 |
782 | zce 1.0 |
783 | zcf 1.0 |
784 | zcmop 1.0 |
785 | zcmp 1.0 |
786 | zcmt 1.0 |
787 | zba 1.0 |
788 | zbb 1.0 |
789 | zbc 1.0 |
790 | zbkb 1.0 |
791 | zbkc 1.0 |
792 | zbkx 1.0 |
793 | zbs 1.0 |
794 | zk 1.0 |
795 | zkn 1.0 |
796 | zknd 1.0 |
797 | zkne 1.0 |
798 | zknh 1.0 |
799 | zkr 1.0 |
800 | zks 1.0 |
801 | zksed 1.0 |
802 | zksh 1.0 |
803 | zkt 1.0 |
804 | zvbb 1.0 |
805 | zvbc 1.0 |
806 | zve32f 1.0 |
807 | zve32x 1.0 |
808 | zve64d 1.0 |
809 | zve64f 1.0 |
810 | zve64x 1.0 |
811 | zvfh 1.0 |
812 | zvfhmin 1.0 |
813 | zvkb 1.0 |
814 | zvkg 1.0 |
815 | zvkn 1.0 |
816 | zvknc 1.0 |
817 | zvkned 1.0 |
818 | zvkng 1.0 |
819 | zvknha 1.0 |
820 | zvknhb 1.0 |
821 | zvks 1.0 |
822 | zvksc 1.0 |
823 | zvksed 1.0 |
824 | zvksg 1.0 |
825 | zvksh 1.0 |
826 | zvkt 1.0 |
827 | zvl1024b 1.0 |
828 | zvl128b 1.0 |
829 | zvl16384b 1.0 |
830 | zvl2048b 1.0 |
831 | zvl256b 1.0 |
832 | zvl32768b 1.0 |
833 | zvl32b 1.0 |
834 | zvl4096b 1.0 |
835 | zvl512b 1.0 |
836 | zvl64b 1.0 |
837 | zvl65536b 1.0 |
838 | zvl8192b 1.0 |
839 | zhinx 1.0 |
840 | zhinxmin 1.0 |
841 | shcounterenw 1.0 |
842 | shgatpa 1.0 |
843 | shtvala 1.0 |
844 | shvsatpa 1.0 |
845 | shvstvala 1.0 |
846 | shvstvecd 1.0 |
847 | smaia 1.0 |
848 | smepmp 1.0 |
849 | ssaia 1.0 |
850 | ssccptr 1.0 |
851 | sscofpmf 1.0 |
852 | sscounterenw 1.0 |
853 | ssstateen 1.0 |
854 | ssstrict 1.0 |
855 | sstc 1.0 |
856 | sstvala 1.0 |
857 | sstvecd 1.0 |
858 | ssu64xl 1.0 |
859 | svade 1.0 |
860 | svadu 1.0 |
861 | svbare 1.0 |
862 | svinval 1.0 |
863 | svnapot 1.0 |
864 | svpbmt 1.0 |
865 | xcvalu 1.0 |
866 | xcvbi 1.0 |
867 | xcvbitmanip 1.0 |
868 | xcvelw 1.0 |
869 | xcvmac 1.0 |
870 | xcvmem 1.0 |
871 | xcvsimd 1.0 |
872 | xsfcease 1.0 |
873 | xsfvcp 1.0 |
874 | xsfvfnrclipxfqf 1.0 |
875 | xsfvfwmaccqqq 1.0 |
876 | xsfvqmaccdod 1.0 |
877 | xsfvqmaccqoq 1.0 |
878 | xsifivecdiscarddlone 1.0 |
879 | xsifivecflushdlone 1.0 |
880 | xtheadba 1.0 |
881 | xtheadbb 1.0 |
882 | xtheadbs 1.0 |
883 | xtheadcmo 1.0 |
884 | xtheadcondmov 1.0 |
885 | xtheadfmemidx 1.0 |
886 | xtheadmac 1.0 |
887 | xtheadmemidx 1.0 |
888 | xtheadmempair 1.0 |
889 | xtheadsync 1.0 |
890 | xtheadvdot 1.0 |
891 | xventanacondops 1.0 |
892 | |
893 | Experimental extensions |
894 | zicfilp 0.4 This is a long dummy description |
895 | zicfiss 0.4 |
896 | zaamo 0.2 |
897 | zabha 1.0 |
898 | zalasr 0.1 |
899 | zalrsc 0.2 |
900 | zfbfmin 1.0 |
901 | ztso 0.1 |
902 | zvfbfmin 1.0 |
903 | zvfbfwma 1.0 |
904 | smmpm 0.8 |
905 | smnpm 0.8 |
906 | ssnpm 0.8 |
907 | sspm 0.8 |
908 | ssqosid 1.0 |
909 | supm 0.8 |
910 | |
911 | Use -march to specify the target's extension. |
912 | For example, clang -march=rv32i_v1p0)" ; |
913 | // clang-format on |
914 | |
915 | StringMap<StringRef> DummyMap; |
916 | DummyMap["i" ] = "This is a long dummy description" ; |
917 | DummyMap["experimental-zicfilp" ] = "This is a long dummy description" ; |
918 | |
919 | outs().flush(); |
920 | testing::internal::CaptureStdout(); |
921 | riscvExtensionsHelp(DescMap: DummyMap); |
922 | outs().flush(); |
923 | |
924 | std::string CapturedOutput = testing::internal::GetCapturedStdout(); |
925 | EXPECT_TRUE([](std::string &Captured, std::string &Expected) { |
926 | return Captured.find(Expected) != std::string::npos; |
927 | }(CapturedOutput, ExpectedOutput)); |
928 | } |
929 | |