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