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