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