xref: /llvm-project/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (revision 24c39261e62d9f99bab91edf67bb9607a681b038)
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(), 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(ParseArchString, RejectsUnrecognizedProfileNames) {
671   for (StringRef Input : {"rvi23u99", "rvz23u64", "rva99u32"}) {
672     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
673               "string must begin with rv32{i,e,g}, rv64{i,e,g}, or a supported "
674               "profile name");
675   }
676 }
677 
678 TEST(ParseArchString, RejectsProfilesWithUnseparatedExtraExtensions) {
679   for (StringRef Input : {"rvi20u32m", "rvi20u64c"}) {
680     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
681               "additional extensions must be after separator '_'");
682   }
683 }
684 
685 TEST(ParseArchString, AcceptsBareProfileNames) {
686   auto MaybeRVA20U64 = RISCVISAInfo::parseArchString("rva20u64", true);
687   ASSERT_THAT_EXPECTED(MaybeRVA20U64, Succeeded());
688   const auto &Exts = (*MaybeRVA20U64)->getExtensions();
689   EXPECT_EQ(Exts.size(), 13UL);
690   EXPECT_EQ(Exts.count("i"), 1U);
691   EXPECT_EQ(Exts.count("m"), 1U);
692   EXPECT_EQ(Exts.count("f"), 1U);
693   EXPECT_EQ(Exts.count("a"), 1U);
694   EXPECT_EQ(Exts.count("d"), 1U);
695   EXPECT_EQ(Exts.count("c"), 1U);
696   EXPECT_EQ(Exts.count("za128rs"), 1U);
697   EXPECT_EQ(Exts.count("zicntr"), 1U);
698   EXPECT_EQ(Exts.count("ziccif"), 1U);
699   EXPECT_EQ(Exts.count("zicsr"), 1U);
700   EXPECT_EQ(Exts.count("ziccrse"), 1U);
701   EXPECT_EQ(Exts.count("ziccamoa"), 1U);
702   EXPECT_EQ(Exts.count("zicclsm"), 1U);
703 
704   auto MaybeRVA23U64 = RISCVISAInfo::parseArchString("rva23u64", true);
705   ASSERT_THAT_EXPECTED(MaybeRVA23U64, Succeeded());
706   EXPECT_GT((*MaybeRVA23U64)->getExtensions().size(), 13UL);
707 }
708 
709 TEST(ParseArchSTring, AcceptsProfileNamesWithSeparatedAdditionalExtensions) {
710   auto MaybeRVI20U64 = RISCVISAInfo::parseArchString("rvi20u64_m_zba", true);
711   ASSERT_THAT_EXPECTED(MaybeRVI20U64, Succeeded());
712   const auto &Exts = (*MaybeRVI20U64)->getExtensions();
713   EXPECT_EQ(Exts.size(), 3UL);
714   EXPECT_EQ(Exts.count("i"), 1U);
715   EXPECT_EQ(Exts.count("m"), 1U);
716   EXPECT_EQ(Exts.count("zba"), 1U);
717 }
718 
719 TEST(ParseArchString,
720      RejectsProfilesWithAdditionalExtensionsGivenAlreadyInProfile) {
721   // This test was added to document the current behaviour. Discussion isn't
722   // believed to have taken place about if this is desirable or not.
723   EXPECT_EQ(
724       toString(
725           RISCVISAInfo::parseArchString("rva20u64_zicntr", true).takeError()),
726       "duplicated standard user-level extension 'zicntr'");
727 }
728 
729 TEST(ToFeatures, IIsDroppedAndExperimentalExtensionsArePrefixed) {
730   auto MaybeISAInfo1 =
731       RISCVISAInfo::parseArchString("rv64im_ztso", true, false);
732   ASSERT_THAT_EXPECTED(MaybeISAInfo1, Succeeded());
733   EXPECT_THAT((*MaybeISAInfo1)->toFeatures(),
734               ElementsAre("+m", "+experimental-ztso"));
735 
736   auto MaybeISAInfo2 =
737       RISCVISAInfo::parseArchString("rv32e_ztso_xventanacondops", true, false);
738   ASSERT_THAT_EXPECTED(MaybeISAInfo2, Succeeded());
739   EXPECT_THAT((*MaybeISAInfo2)->toFeatures(),
740               ElementsAre("+e", "+experimental-ztso", "+xventanacondops"));
741 }
742 
743 TEST(ToFeatures, UnsupportedExtensionsAreDropped) {
744   auto MaybeISAInfo =
745       RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0_xmadeup1p0");
746   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
747   EXPECT_THAT((*MaybeISAInfo)->toFeatures(), ElementsAre("+m"));
748 }
749 
750 TEST(ToFeatures, UnsupportedExtensionsAreKeptIfIgnoreUnknownIsFalse) {
751   auto MaybeISAInfo =
752       RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0_xmadeup1p0");
753   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
754   EXPECT_THAT((*MaybeISAInfo)->toFeatures(false, false),
755               ElementsAre("+m", "+xmadeup"));
756 }
757 
758 TEST(ToFeatures, AddAllExtensionsAddsNegativeExtensions) {
759   auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0");
760   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
761 
762   auto Features = (*MaybeISAInfo)->toFeatures(true);
763   EXPECT_GT(Features.size(), 1UL);
764   EXPECT_EQ(Features.front(), "+m");
765   // Every feature after should be a negative feature
766   for (auto &NegativeExt : llvm::drop_begin(Features))
767     EXPECT_TRUE(NegativeExt.substr(0, 1) == "-");
768 }
769 
770 TEST(OrderedExtensionMap, ExtensionsAreCorrectlyOrdered) {
771   RISCVISAUtils::OrderedExtensionMap Exts;
772   for (auto ExtName : {"y", "l", "m", "c", "i", "xfoo", "xbar", "sfoo", "sbar",
773                        "zmfoo", "zzfoo", "zfinx", "zicsr"})
774     Exts[ExtName] = {1, 0};
775 
776   std::vector<std::string> ExtNames;
777   for (const auto &Ext : Exts)
778     ExtNames.push_back(Ext.first);
779 
780   // FIXME: 'l' and 'y' should be ordered after 'i', 'm', 'c'.
781   EXPECT_THAT(ExtNames,
782               ElementsAre("i", "m", "l", "c", "y", "zicsr", "zmfoo", "zfinx",
783                            "zzfoo", "sbar", "sfoo", "xbar", "xfoo"));
784 }
785 
786 TEST(ParseArchString, ZceImplication) {
787   auto MaybeRV32IZce = RISCVISAInfo::parseArchString("rv32izce", true);
788   ASSERT_THAT_EXPECTED(MaybeRV32IZce, Succeeded());
789   const auto &ExtsRV32IZce = (*MaybeRV32IZce)->getExtensions();
790   EXPECT_EQ(ExtsRV32IZce.size(), 7UL);
791   EXPECT_EQ(ExtsRV32IZce.count("i"), 1U);
792   EXPECT_EQ(ExtsRV32IZce.count("zicsr"), 1U);
793   EXPECT_EQ(ExtsRV32IZce.count("zca"), 1U);
794   EXPECT_EQ(ExtsRV32IZce.count("zcb"), 1U);
795   EXPECT_EQ(ExtsRV32IZce.count("zce"), 1U);
796   EXPECT_EQ(ExtsRV32IZce.count("zcmp"), 1U);
797   EXPECT_EQ(ExtsRV32IZce.count("zcmt"), 1U);
798 
799   auto MaybeRV32IFZce = RISCVISAInfo::parseArchString("rv32ifzce", true);
800   ASSERT_THAT_EXPECTED(MaybeRV32IFZce, Succeeded());
801   const auto &ExtsRV32IFZce = (*MaybeRV32IFZce)->getExtensions();
802   EXPECT_EQ(ExtsRV32IFZce.size(), 9UL);
803   EXPECT_EQ(ExtsRV32IFZce.count("i"), 1U);
804   EXPECT_EQ(ExtsRV32IFZce.count("zicsr"), 1U);
805   EXPECT_EQ(ExtsRV32IFZce.count("f"), 1U);
806   EXPECT_EQ(ExtsRV32IFZce.count("zca"), 1U);
807   EXPECT_EQ(ExtsRV32IFZce.count("zcb"), 1U);
808   EXPECT_EQ(ExtsRV32IFZce.count("zce"), 1U);
809   EXPECT_EQ(ExtsRV32IFZce.count("zcf"), 1U);
810   EXPECT_EQ(ExtsRV32IFZce.count("zcmp"), 1U);
811   EXPECT_EQ(ExtsRV32IFZce.count("zcmt"), 1U);
812 
813   auto MaybeRV32IDZce = RISCVISAInfo::parseArchString("rv32idzce", true);
814   ASSERT_THAT_EXPECTED(MaybeRV32IDZce, Succeeded());
815   const auto &ExtsRV32IDZce = (*MaybeRV32IDZce)->getExtensions();
816   EXPECT_EQ(ExtsRV32IDZce.size(), 10UL);
817   EXPECT_EQ(ExtsRV32IDZce.count("i"), 1U);
818   EXPECT_EQ(ExtsRV32IDZce.count("zicsr"), 1U);
819   EXPECT_EQ(ExtsRV32IDZce.count("f"), 1U);
820   EXPECT_EQ(ExtsRV32IDZce.count("d"), 1U);
821   EXPECT_EQ(ExtsRV32IDZce.count("zca"), 1U);
822   EXPECT_EQ(ExtsRV32IDZce.count("zcb"), 1U);
823   EXPECT_EQ(ExtsRV32IDZce.count("zce"), 1U);
824   EXPECT_EQ(ExtsRV32IDZce.count("zcf"), 1U);
825   EXPECT_EQ(ExtsRV32IDZce.count("zcmp"), 1U);
826   EXPECT_EQ(ExtsRV32IDZce.count("zcmt"), 1U);
827 
828   auto MaybeRV64IZce = RISCVISAInfo::parseArchString("rv64izce", true);
829   ASSERT_THAT_EXPECTED(MaybeRV64IZce, Succeeded());
830   const auto &ExtsRV64IZce = (*MaybeRV64IZce)->getExtensions();
831   EXPECT_EQ(ExtsRV64IZce.size(), 7UL);
832   EXPECT_EQ(ExtsRV64IZce.count("i"), 1U);
833   EXPECT_EQ(ExtsRV64IZce.count("zicsr"), 1U);
834   EXPECT_EQ(ExtsRV64IZce.count("zca"), 1U);
835   EXPECT_EQ(ExtsRV64IZce.count("zcb"), 1U);
836   EXPECT_EQ(ExtsRV64IZce.count("zce"), 1U);
837   EXPECT_EQ(ExtsRV64IZce.count("zcmp"), 1U);
838   EXPECT_EQ(ExtsRV64IZce.count("zcmt"), 1U);
839 
840   auto MaybeRV64IFZce = RISCVISAInfo::parseArchString("rv64ifzce", true);
841   ASSERT_THAT_EXPECTED(MaybeRV64IFZce, Succeeded());
842   const auto &ExtsRV64IFZce = (*MaybeRV64IFZce)->getExtensions();
843   EXPECT_EQ(ExtsRV64IFZce.size(), 8UL);
844   EXPECT_EQ(ExtsRV64IFZce.count("i"), 1U);
845   EXPECT_EQ(ExtsRV64IFZce.count("zicsr"), 1U);
846   EXPECT_EQ(ExtsRV64IFZce.count("f"), 1U);
847   EXPECT_EQ(ExtsRV64IFZce.count("zca"), 1U);
848   EXPECT_EQ(ExtsRV64IFZce.count("zcb"), 1U);
849   EXPECT_EQ(ExtsRV64IFZce.count("zce"), 1U);
850   EXPECT_EQ(ExtsRV64IFZce.count("zcmp"), 1U);
851   EXPECT_EQ(ExtsRV64IFZce.count("zcmt"), 1U);
852 
853   EXPECT_EQ(ExtsRV64IFZce.count("zca"), 1U);
854   EXPECT_EQ(ExtsRV64IFZce.count("zcb"), 1U);
855   EXPECT_EQ(ExtsRV64IFZce.count("zce"), 1U);
856   EXPECT_EQ(ExtsRV64IFZce.count("zcmp"), 1U);
857   EXPECT_EQ(ExtsRV64IFZce.count("zcmt"), 1U);
858 
859   auto MaybeRV64IDZce = RISCVISAInfo::parseArchString("rv64idzce", true);
860   ASSERT_THAT_EXPECTED(MaybeRV64IDZce, Succeeded());
861   const auto &ExtsRV64IDZce = (*MaybeRV64IDZce)->getExtensions();
862   EXPECT_EQ(ExtsRV64IDZce.size(), 9UL);
863   EXPECT_EQ(ExtsRV64IDZce.count("i"), 1U);
864   EXPECT_EQ(ExtsRV64IDZce.count("zicsr"), 1U);
865   EXPECT_EQ(ExtsRV64IDZce.count("f"), 1U);
866   EXPECT_EQ(ExtsRV64IDZce.count("d"), 1U);
867   EXPECT_EQ(ExtsRV64IDZce.count("zca"), 1U);
868   EXPECT_EQ(ExtsRV64IDZce.count("zcb"), 1U);
869   EXPECT_EQ(ExtsRV64IDZce.count("zce"), 1U);
870   EXPECT_EQ(ExtsRV64IDZce.count("zcmp"), 1U);
871   EXPECT_EQ(ExtsRV64IDZce.count("zcmt"), 1U);
872 }
873 
874 TEST(isSupportedExtensionWithVersion, AcceptsSingleExtensionWithVersion) {
875   EXPECT_TRUE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb1p0"));
876   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb"));
877   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo1p0"));
878   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo"));
879   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion(""));
880   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("c2p0zbb1p0"));
881 }
882 
883 TEST(getTargetFeatureForExtension, RetrieveTargetFeatureFromOneExt) {
884   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbb"), "zbb");
885   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso0p1"),
886             "experimental-ztso");
887   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso"),
888             "experimental-ztso");
889   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zihintntl1234p4321"),
890             "");
891   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zfoo"), "");
892   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension(""), "");
893   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbbzihintntl"), "");
894 }
895 
896 TEST(RiscvExtensionsHelp, CheckExtensions) {
897   // clang-format off
898   std::string ExpectedOutput =
899 R"(All available -march extensions for RISC-V
900 
901     Name                 Version   Description
902     i                    2.1       This is a long dummy description
903     e                    2.0
904     m                    2.0
905     a                    2.1
906     f                    2.2
907     d                    2.2
908     c                    2.0
909     v                    1.0
910     h                    1.0
911     zic64b               1.0
912     zicbom               1.0
913     zicbop               1.0
914     zicboz               1.0
915     ziccamoa             1.0
916     ziccif               1.0
917     zicclsm              1.0
918     ziccrse              1.0
919     zicntr               2.0
920     zicond               1.0
921     zicsr                2.0
922     zifencei             2.0
923     zihintntl            1.0
924     zihintpause          2.0
925     zihpm                2.0
926     zimop                1.0
927     zmmul                1.0
928     za128rs              1.0
929     za64rs               1.0
930     zacas                1.0
931     zama16b              1.0
932     zawrs                1.0
933     zfa                  1.0
934     zfh                  1.0
935     zfhmin               1.0
936     zfinx                1.0
937     zdinx                1.0
938     zca                  1.0
939     zcb                  1.0
940     zcd                  1.0
941     zce                  1.0
942     zcf                  1.0
943     zcmop                1.0
944     zcmp                 1.0
945     zcmt                 1.0
946     zba                  1.0
947     zbb                  1.0
948     zbc                  1.0
949     zbkb                 1.0
950     zbkc                 1.0
951     zbkx                 1.0
952     zbs                  1.0
953     zk                   1.0
954     zkn                  1.0
955     zknd                 1.0
956     zkne                 1.0
957     zknh                 1.0
958     zkr                  1.0
959     zks                  1.0
960     zksed                1.0
961     zksh                 1.0
962     zkt                  1.0
963     zvbb                 1.0
964     zvbc                 1.0
965     zve32f               1.0
966     zve32x               1.0
967     zve64d               1.0
968     zve64f               1.0
969     zve64x               1.0
970     zvfh                 1.0
971     zvfhmin              1.0
972     zvkb                 1.0
973     zvkg                 1.0
974     zvkn                 1.0
975     zvknc                1.0
976     zvkned               1.0
977     zvkng                1.0
978     zvknha               1.0
979     zvknhb               1.0
980     zvks                 1.0
981     zvksc                1.0
982     zvksed               1.0
983     zvksg                1.0
984     zvksh                1.0
985     zvkt                 1.0
986     zvl1024b             1.0
987     zvl128b              1.0
988     zvl16384b            1.0
989     zvl2048b             1.0
990     zvl256b              1.0
991     zvl32768b            1.0
992     zvl32b               1.0
993     zvl4096b             1.0
994     zvl512b              1.0
995     zvl64b               1.0
996     zvl65536b            1.0
997     zvl8192b             1.0
998     zhinx                1.0
999     zhinxmin             1.0
1000     shcounterenw         1.0
1001     shgatpa              1.0
1002     shtvala              1.0
1003     shvsatpa             1.0
1004     shvstvala            1.0
1005     shvstvecd            1.0
1006     smaia                1.0
1007     smepmp               1.0
1008     smstateen            1.0
1009     ssaia                1.0
1010     ssccptr              1.0
1011     sscofpmf             1.0
1012     sscounterenw         1.0
1013     ssstateen            1.0
1014     ssstrict             1.0
1015     sstc                 1.0
1016     sstvala              1.0
1017     sstvecd              1.0
1018     ssu64xl              1.0
1019     svade                1.0
1020     svadu                1.0
1021     svbare               1.0
1022     svinval              1.0
1023     svnapot              1.0
1024     svpbmt               1.0
1025     xcvalu               1.0
1026     xcvbi                1.0
1027     xcvbitmanip          1.0
1028     xcvelw               1.0
1029     xcvmac               1.0
1030     xcvmem               1.0
1031     xcvsimd              1.0
1032     xsfcease             1.0
1033     xsfvcp               1.0
1034     xsfvfnrclipxfqf      1.0
1035     xsfvfwmaccqqq        1.0
1036     xsfvqmaccdod         1.0
1037     xsfvqmaccqoq         1.0
1038     xsifivecdiscarddlone 1.0
1039     xsifivecflushdlone   1.0
1040     xtheadba             1.0
1041     xtheadbb             1.0
1042     xtheadbs             1.0
1043     xtheadcmo            1.0
1044     xtheadcondmov        1.0
1045     xtheadfmemidx        1.0
1046     xtheadmac            1.0
1047     xtheadmemidx         1.0
1048     xtheadmempair        1.0
1049     xtheadsync           1.0
1050     xtheadvdot           1.0
1051     xventanacondops      1.0
1052 
1053 Experimental extensions
1054     zicfilp              0.4       This is a long dummy description
1055     zicfiss              0.4
1056     zaamo                0.2
1057     zabha                1.0
1058     zalasr               0.1
1059     zalrsc               0.2
1060     zfbfmin              1.0
1061     ztso                 0.1
1062     zvfbfmin             1.0
1063     zvfbfwma             1.0
1064     smmpm                0.8
1065     smnpm                0.8
1066     ssnpm                0.8
1067     sspm                 0.8
1068     ssqosid              1.0
1069     supm                 0.8
1070 
1071 Supported Profiles
1072     rva20s64
1073     rva20u64
1074     rva22s64
1075     rva22u64
1076     rva23s64
1077     rva23u64
1078     rvb23s64
1079     rvb23u64
1080     rvi20u32
1081     rvi20u64
1082     rvm23u32
1083 
1084 Use -march to specify the target's extension.
1085 For example, clang -march=rv32i_v1p0)";
1086   // clang-format on
1087 
1088   StringMap<StringRef> DummyMap;
1089   DummyMap["i"] = "This is a long dummy description";
1090   DummyMap["experimental-zicfilp"] = "This is a long dummy description";
1091 
1092   outs().flush();
1093   testing::internal::CaptureStdout();
1094   riscvExtensionsHelp(DummyMap);
1095   outs().flush();
1096 
1097   std::string CapturedOutput = testing::internal::GetCapturedStdout();
1098   EXPECT_TRUE([](std::string &Captured, std::string &Expected) {
1099                 return Captured.find(Expected) != std::string::npos;
1100               }(CapturedOutput, ExpectedOutput));
1101 }
1102