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