xref: /llvm-project/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (revision a80a90e34b1f26422ebf56e922abe2c193607c81)
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     zalrsc               1.0
896     zama16b              1.0
897     zawrs                1.0
898     zfa                  1.0
899     zfbfmin              1.0
900     zfh                  1.0
901     zfhmin               1.0
902     zfinx                1.0
903     zdinx                1.0
904     zca                  1.0
905     zcb                  1.0
906     zcd                  1.0
907     zce                  1.0
908     zcf                  1.0
909     zcmop                1.0
910     zcmp                 1.0
911     zcmt                 1.0
912     zba                  1.0
913     zbb                  1.0
914     zbc                  1.0
915     zbkb                 1.0
916     zbkc                 1.0
917     zbkx                 1.0
918     zbs                  1.0
919     zk                   1.0
920     zkn                  1.0
921     zknd                 1.0
922     zkne                 1.0
923     zknh                 1.0
924     zkr                  1.0
925     zks                  1.0
926     zksed                1.0
927     zksh                 1.0
928     zkt                  1.0
929     ztso                 1.0
930     zvbb                 1.0
931     zvbc                 1.0
932     zve32f               1.0
933     zve32x               1.0
934     zve64d               1.0
935     zve64f               1.0
936     zve64x               1.0
937     zvfbfmin             1.0
938     zvfbfwma             1.0
939     zvfh                 1.0
940     zvfhmin              1.0
941     zvkb                 1.0
942     zvkg                 1.0
943     zvkn                 1.0
944     zvknc                1.0
945     zvkned               1.0
946     zvkng                1.0
947     zvknha               1.0
948     zvknhb               1.0
949     zvks                 1.0
950     zvksc                1.0
951     zvksed               1.0
952     zvksg                1.0
953     zvksh                1.0
954     zvkt                 1.0
955     zvl1024b             1.0
956     zvl128b              1.0
957     zvl16384b            1.0
958     zvl2048b             1.0
959     zvl256b              1.0
960     zvl32768b            1.0
961     zvl32b               1.0
962     zvl4096b             1.0
963     zvl512b              1.0
964     zvl64b               1.0
965     zvl65536b            1.0
966     zvl8192b             1.0
967     zhinx                1.0
968     zhinxmin             1.0
969     shcounterenw         1.0
970     shgatpa              1.0
971     shtvala              1.0
972     shvsatpa             1.0
973     shvstvala            1.0
974     shvstvecd            1.0
975     smaia                1.0
976     smcdeleg             1.0
977     smcsrind             1.0
978     smepmp               1.0
979     smstateen            1.0
980     ssaia                1.0
981     ssccfg               1.0
982     ssccptr              1.0
983     sscofpmf             1.0
984     sscounterenw         1.0
985     sscsrind             1.0
986     ssstateen            1.0
987     ssstrict             1.0
988     sstc                 1.0
989     sstvala              1.0
990     sstvecd              1.0
991     ssu64xl              1.0
992     svade                1.0
993     svadu                1.0
994     svbare               1.0
995     svinval              1.0
996     svnapot              1.0
997     svpbmt               1.0
998     xcvalu               1.0
999     xcvbi                1.0
1000     xcvbitmanip          1.0
1001     xcvelw               1.0
1002     xcvmac               1.0
1003     xcvmem               1.0
1004     xcvsimd              1.0
1005     xsfcease             1.0
1006     xsfvcp               1.0
1007     xsfvfnrclipxfqf      1.0
1008     xsfvfwmaccqqq        1.0
1009     xsfvqmaccdod         1.0
1010     xsfvqmaccqoq         1.0
1011     xsifivecdiscarddlone 1.0
1012     xsifivecflushdlone   1.0
1013     xtheadba             1.0
1014     xtheadbb             1.0
1015     xtheadbs             1.0
1016     xtheadcmo            1.0
1017     xtheadcondmov        1.0
1018     xtheadfmemidx        1.0
1019     xtheadmac            1.0
1020     xtheadmemidx         1.0
1021     xtheadmempair        1.0
1022     xtheadsync           1.0
1023     xtheadvdot           1.0
1024     xventanacondops      1.0
1025     xwchc                2.2
1026 
1027 Experimental extensions
1028     zicfilp              1.0       This is a long dummy description
1029     zicfiss              1.0
1030     zacas                1.0
1031     zalasr               0.1
1032     zvbc32e              0.7
1033     zvkgs                0.7
1034     smmpm                1.0
1035     smnpm                1.0
1036     ssnpm                1.0
1037     sspm                 1.0
1038     ssqosid              1.0
1039     supm                 1.0
1040 
1041 Supported Profiles
1042     rva20s64
1043     rva20u64
1044     rva22s64
1045     rva22u64
1046     rvi20u32
1047     rvi20u64
1048 
1049 Experimental Profiles
1050     rva23s64
1051     rva23u64
1052     rvb23s64
1053     rvb23u64
1054     rvm23u32
1055 
1056 Use -march to specify the target's extension.
1057 For example, clang -march=rv32i_v1p0)";
1058   // clang-format on
1059 
1060   StringMap<StringRef> DummyMap;
1061   DummyMap["i"] = "This is a long dummy description";
1062   DummyMap["experimental-zicfilp"] = "This is a long dummy description";
1063 
1064   outs().flush();
1065   testing::internal::CaptureStdout();
1066   RISCVISAInfo::printSupportedExtensions(DummyMap);
1067   outs().flush();
1068 
1069   std::string CapturedOutput = testing::internal::GetCapturedStdout();
1070   EXPECT_TRUE([](std::string &Captured, std::string &Expected) {
1071                 return Captured.find(Expected) != std::string::npos;
1072               }(CapturedOutput, ExpectedOutput));
1073 }
1074 
1075 TEST(TargetParserTest, RISCVPrintEnabledExtensions) {
1076   // clang-format off
1077   std::string ExpectedOutput =
1078 R"(Extensions enabled for the given RISC-V target
1079 
1080     Name                 Version   Description
1081     i                    2.1       'I' (Base Integer Instruction Set)
1082 
1083 Experimental extensions
1084     zicfilp              1.0       'Zicfilp' (Landing pad)
1085 
1086 ISA String: rv64i2p1_zicfilp1p0_zicsr2p0
1087 )";
1088   // clang-format on
1089 
1090   StringMap<StringRef> DescMap;
1091   DescMap["i"] = "'I' (Base Integer Instruction Set)";
1092   DescMap["experimental-zicfilp"] = "'Zicfilp' (Landing pad)";
1093   std::set<StringRef> EnabledExtensions = {"i", "experimental-zicfilp"};
1094 
1095   outs().flush();
1096   testing::internal::CaptureStdout();
1097   RISCVISAInfo::printEnabledExtensions(/*IsRV64=*/true, EnabledExtensions,
1098                                        DescMap);
1099   outs().flush();
1100   std::string CapturedOutput = testing::internal::GetCapturedStdout();
1101 
1102   EXPECT_EQ(CapturedOutput, ExpectedOutput);
1103 }
1104