xref: /llvm-project/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (revision d489b7ccb7b43fe54dfb4b2884d7f1eb2cb5806e)
1 //===-- unittests/RISCVISAInfoTest.cpp ------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/TargetParser/RISCVISAInfo.h"
10 #include "llvm/ADT/StringMap.h"
11 #include "llvm/Testing/Support/Error.h"
12 #include "gtest/gtest.h"
13 
14 using ::testing::ElementsAre;
15 
16 using namespace llvm;
17 
18 bool operator==(const RISCVISAUtils::ExtensionVersion &A,
19                 const RISCVISAUtils::ExtensionVersion &B) {
20   return A.Major == B.Major && A.Minor == B.Minor;
21 }
22 
23 TEST(ParseNormalizedArchString, RejectsInvalidChars) {
24   for (StringRef Input : {"RV32", "rV64", "rv32i2P0", "rv64i2p0_A2p0",
25                           "rv32e2.0", "rva20u64+zbc"}) {
26     EXPECT_EQ(
27         toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
28         "string may only contain [a-z0-9_]");
29   }
30 }
31 
32 TEST(ParseNormalizedArchString, RejectsInvalidBaseISA) {
33   for (StringRef Input : {"rv32", "rv64", "rv32j", "rv65i"}) {
34     EXPECT_EQ(
35         toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
36         "arch string must begin with valid base ISA");
37   }
38 }
39 
40 TEST(ParseNormalizedArchString, RejectsMalformedInputs) {
41   for (StringRef Input : {"rv64e2p", "rv32i", "rv64ip1"}) {
42     EXPECT_EQ(
43         toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
44         "extension lacks version in expected format");
45   }
46 
47   for (StringRef Input : {"rv64i2p0_", "rv32i2p0__a2p0"}) {
48     EXPECT_EQ(
49         toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
50         "extension name missing after separator '_'");
51   }
52 }
53 
54 TEST(ParseNormalizedArchString, RejectsOnlyVersion) {
55   for (StringRef Input : {"rv64i2p0_1p0", "rv32i2p0_1p0"}) {
56     EXPECT_EQ(
57         toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
58         "missing extension name");
59   }
60 }
61 
62 TEST(ParseNormalizedArchString, RejectsBadZ) {
63   for (StringRef Input : {"rv64i2p0_z1p0", "rv32i2p0_z2a1p0"}) {
64     EXPECT_EQ(
65         toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
66         "'z' must be followed by a letter");
67   }
68 }
69 
70 TEST(ParseNormalizedArchString, RejectsBadS) {
71   for (StringRef Input : {"rv64i2p0_s1p0", "rv32i2p0_s2a1p0"}) {
72     EXPECT_EQ(
73         toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
74         "'s' must be followed by a letter");
75   }
76 }
77 
78 TEST(ParseNormalizedArchString, RejectsBadX) {
79   for (StringRef Input : {"rv64i2p0_x1p0", "rv32i2p0_x2a1p0"}) {
80     EXPECT_EQ(
81         toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
82         "'x' must be followed by a letter");
83   }
84 }
85 
86 TEST(ParseNormalizedArchString, DuplicateExtension) {
87   for (StringRef Input : {"rv64i2p0_a2p0_a1p0"}) {
88     EXPECT_EQ(
89         toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
90         "duplicate extension 'a'");
91   }
92 }
93 
94 TEST(ParseNormalizedArchString, AcceptsValidBaseISAsAndSetsXLen) {
95   auto MaybeRV32I = RISCVISAInfo::parseNormalizedArchString("rv32i2p0");
96   ASSERT_THAT_EXPECTED(MaybeRV32I, Succeeded());
97   RISCVISAInfo &InfoRV32I = **MaybeRV32I;
98   EXPECT_EQ(InfoRV32I.getExtensions().size(), 1UL);
99   EXPECT_TRUE(InfoRV32I.getExtensions().at("i") ==
100               (RISCVISAUtils::ExtensionVersion{2, 0}));
101   EXPECT_EQ(InfoRV32I.getXLen(), 32U);
102 
103   auto MaybeRV32E = RISCVISAInfo::parseNormalizedArchString("rv32e2p0");
104   ASSERT_THAT_EXPECTED(MaybeRV32E, Succeeded());
105   RISCVISAInfo &InfoRV32E = **MaybeRV32E;
106   EXPECT_EQ(InfoRV32E.getExtensions().size(), 1UL);
107   EXPECT_TRUE(InfoRV32E.getExtensions().at("e") ==
108               (RISCVISAUtils::ExtensionVersion{2, 0}));
109   EXPECT_EQ(InfoRV32E.getXLen(), 32U);
110 
111   auto MaybeRV64I = RISCVISAInfo::parseNormalizedArchString("rv64i2p0");
112   ASSERT_THAT_EXPECTED(MaybeRV64I, Succeeded());
113   RISCVISAInfo &InfoRV64I = **MaybeRV64I;
114   EXPECT_EQ(InfoRV64I.getExtensions().size(), 1UL);
115   EXPECT_TRUE(InfoRV64I.getExtensions().at("i") ==
116               (RISCVISAUtils::ExtensionVersion{2, 0}));
117   EXPECT_EQ(InfoRV64I.getXLen(), 64U);
118 
119   auto MaybeRV64E = RISCVISAInfo::parseNormalizedArchString("rv64e2p0");
120   ASSERT_THAT_EXPECTED(MaybeRV64E, Succeeded());
121   RISCVISAInfo &InfoRV64E = **MaybeRV64E;
122   EXPECT_EQ(InfoRV64E.getExtensions().size(), 1UL);
123   EXPECT_TRUE(InfoRV64E.getExtensions().at("e") ==
124               (RISCVISAUtils::ExtensionVersion{2, 0}));
125   EXPECT_EQ(InfoRV64E.getXLen(), 64U);
126 }
127 
128 TEST(ParseNormalizedArchString, AcceptsArbitraryExtensionsAndVersions) {
129   auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString(
130       "rv64i5p1_m3p2_zmadeup11p12_sfoo2p0_xbar3p0");
131   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
132   RISCVISAInfo &Info = **MaybeISAInfo;
133   EXPECT_EQ(Info.getExtensions().size(), 5UL);
134   EXPECT_TRUE(Info.getExtensions().at("i") ==
135               (RISCVISAUtils::ExtensionVersion{5, 1}));
136   EXPECT_TRUE(Info.getExtensions().at("m") ==
137               (RISCVISAUtils::ExtensionVersion{3, 2}));
138   EXPECT_TRUE(Info.getExtensions().at("zmadeup") ==
139               (RISCVISAUtils::ExtensionVersion{11, 12}));
140   EXPECT_TRUE(Info.getExtensions().at("sfoo") ==
141               (RISCVISAUtils::ExtensionVersion{2, 0}));
142   EXPECT_TRUE(Info.getExtensions().at("xbar") ==
143               (RISCVISAUtils::ExtensionVersion{3, 0}));
144 }
145 
146 TEST(ParseNormalizedArchString, UpdatesFLenMinVLenMaxELen) {
147   auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString(
148       "rv64i2p0_d2p0_zvl64b1p0_zve64d1p0");
149   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
150   RISCVISAInfo &Info = **MaybeISAInfo;
151   EXPECT_EQ(Info.getXLen(), 64U);
152   EXPECT_EQ(Info.getFLen(), 64U);
153   EXPECT_EQ(Info.getMinVLen(), 64U);
154   EXPECT_EQ(Info.getMaxELen(), 64U);
155   EXPECT_EQ(Info.getMaxELenFp(), 64U);
156 }
157 
158 TEST(ParseNormalizedArchString, AcceptsUnknownMultiletter) {
159   auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString(
160       "rv64i2p0_f2p0_d2p0_zicsr2p0_ykk1p0");
161   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
162   RISCVISAInfo &Info = **MaybeISAInfo;
163   EXPECT_EQ(Info.toString(), "rv64i2p0_f2p0_d2p0_zicsr2p0_ykk1p0");
164 }
165 
166 TEST(ParseArchString, RejectsInvalidChars) {
167   for (StringRef Input : {"RV32", "rV64", "rv32i2P0", "rv64i2p0_A2p0"}) {
168     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
169               "string may only contain [a-z0-9_]");
170   }
171 }
172 
173 TEST(ParseArchString, RejectsInvalidBaseISA) {
174   for (StringRef Input : {"rv32", "rv64", "rv65i"}) {
175     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
176               "string must begin with rv32{i,e,g}, rv64{i,e,g}, or a supported "
177               "profile name");
178   }
179 
180   for (StringRef Input : {"rv32j", "rv32_i"}) {
181     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
182               "first letter after 'rv32' should be 'e', 'i' or 'g'");
183   }
184 
185   EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv64k", true).takeError()),
186             "first letter after 'rv64' should be 'e', 'i' or 'g'");
187 }
188 
189 TEST(ParseArchString, RejectsUnsupportedBaseISA) {
190   for (StringRef Input : {"rv128i", "rv128g"}) {
191     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
192               "string must begin with rv32{i,e,g}, rv64{i,e,g}, or a supported "
193               "profile name");
194   }
195 }
196 
197 TEST(ParseArchString, AcceptsSupportedBaseISAsAndSetsXLenAndFLen) {
198   auto MaybeRV32I = RISCVISAInfo::parseArchString("rv32i", true);
199   ASSERT_THAT_EXPECTED(MaybeRV32I, Succeeded());
200   RISCVISAInfo &InfoRV32I = **MaybeRV32I;
201   const auto &ExtsRV32I = InfoRV32I.getExtensions();
202   EXPECT_EQ(ExtsRV32I.size(), 1UL);
203   EXPECT_TRUE(ExtsRV32I.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
204   EXPECT_EQ(InfoRV32I.getXLen(), 32U);
205   EXPECT_EQ(InfoRV32I.getFLen(), 0U);
206   EXPECT_EQ(InfoRV32I.getMinVLen(), 0U);
207   EXPECT_EQ(InfoRV32I.getMaxELen(), 0U);
208   EXPECT_EQ(InfoRV32I.getMaxELenFp(), 0U);
209 
210   auto MaybeRV32E = RISCVISAInfo::parseArchString("rv32e", true);
211   ASSERT_THAT_EXPECTED(MaybeRV32E, Succeeded());
212   RISCVISAInfo &InfoRV32E = **MaybeRV32E;
213   const auto &ExtsRV32E = InfoRV32E.getExtensions();
214   EXPECT_EQ(ExtsRV32E.size(), 1UL);
215   EXPECT_TRUE(ExtsRV32E.at("e") == (RISCVISAUtils::ExtensionVersion{2, 0}));
216   EXPECT_EQ(InfoRV32E.getXLen(), 32U);
217   EXPECT_EQ(InfoRV32E.getFLen(), 0U);
218   EXPECT_EQ(InfoRV32E.getMinVLen(), 0U);
219   EXPECT_EQ(InfoRV32E.getMaxELen(), 0U);
220   EXPECT_EQ(InfoRV32E.getMaxELenFp(), 0U);
221 
222   auto MaybeRV32G = RISCVISAInfo::parseArchString("rv32g", true);
223   ASSERT_THAT_EXPECTED(MaybeRV32G, Succeeded());
224   RISCVISAInfo &InfoRV32G = **MaybeRV32G;
225   const auto &ExtsRV32G = InfoRV32G.getExtensions();
226   EXPECT_EQ(ExtsRV32G.size(), 8UL);
227   EXPECT_TRUE(ExtsRV32G.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
228   EXPECT_TRUE(ExtsRV32G.at("m") == (RISCVISAUtils::ExtensionVersion{2, 0}));
229   EXPECT_TRUE(ExtsRV32G.at("a") == (RISCVISAUtils::ExtensionVersion{2, 1}));
230   EXPECT_TRUE(ExtsRV32G.at("f") == (RISCVISAUtils::ExtensionVersion{2, 2}));
231   EXPECT_TRUE(ExtsRV32G.at("d") == (RISCVISAUtils::ExtensionVersion{2, 2}));
232   EXPECT_TRUE(ExtsRV32G.at("zicsr") == (RISCVISAUtils::ExtensionVersion{2, 0}));
233   EXPECT_TRUE(ExtsRV32G.at("zifencei") ==
234               (RISCVISAUtils::ExtensionVersion{2, 0}));
235   EXPECT_TRUE(ExtsRV32G.at("zmmul") == (RISCVISAUtils::ExtensionVersion{1, 0}));
236   EXPECT_EQ(InfoRV32G.getXLen(), 32U);
237   EXPECT_EQ(InfoRV32G.getFLen(), 64U);
238   EXPECT_EQ(InfoRV32G.getMinVLen(), 0U);
239   EXPECT_EQ(InfoRV32G.getMaxELen(), 0U);
240   EXPECT_EQ(InfoRV32G.getMaxELenFp(), 0U);
241 
242   auto MaybeRV64I = RISCVISAInfo::parseArchString("rv64i", true);
243   ASSERT_THAT_EXPECTED(MaybeRV64I, Succeeded());
244   RISCVISAInfo &InfoRV64I = **MaybeRV64I;
245   const auto &ExtsRV64I = InfoRV64I.getExtensions();
246   EXPECT_EQ(ExtsRV64I.size(), 1UL);
247   EXPECT_TRUE(ExtsRV64I.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
248   EXPECT_EQ(InfoRV64I.getXLen(), 64U);
249   EXPECT_EQ(InfoRV64I.getFLen(), 0U);
250   EXPECT_EQ(InfoRV64I.getMinVLen(), 0U);
251   EXPECT_EQ(InfoRV64I.getMaxELen(), 0U);
252   EXPECT_EQ(InfoRV64I.getMaxELenFp(), 0U);
253 
254   auto MaybeRV64E = RISCVISAInfo::parseArchString("rv64e", true);
255   ASSERT_THAT_EXPECTED(MaybeRV64E, Succeeded());
256   RISCVISAInfo &InfoRV64E = **MaybeRV64E;
257   const auto &ExtsRV64E = InfoRV64E.getExtensions();
258   EXPECT_EQ(ExtsRV64E.size(), 1UL);
259   EXPECT_TRUE(ExtsRV64E.at("e") == (RISCVISAUtils::ExtensionVersion{2, 0}));
260   EXPECT_EQ(InfoRV64E.getXLen(), 64U);
261   EXPECT_EQ(InfoRV64E.getFLen(), 0U);
262   EXPECT_EQ(InfoRV64E.getMinVLen(), 0U);
263   EXPECT_EQ(InfoRV64E.getMaxELen(), 0U);
264   EXPECT_EQ(InfoRV64E.getMaxELenFp(), 0U);
265 
266   auto MaybeRV64G = RISCVISAInfo::parseArchString("rv64g", true);
267   ASSERT_THAT_EXPECTED(MaybeRV64G, Succeeded());
268   RISCVISAInfo &InfoRV64G = **MaybeRV64G;
269   const auto &ExtsRV64G = InfoRV64G.getExtensions();
270   EXPECT_EQ(ExtsRV64G.size(), 8UL);
271   EXPECT_TRUE(ExtsRV64G.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
272   EXPECT_TRUE(ExtsRV64G.at("m") == (RISCVISAUtils::ExtensionVersion{2, 0}));
273   EXPECT_TRUE(ExtsRV64G.at("a") == (RISCVISAUtils::ExtensionVersion{2, 1}));
274   EXPECT_TRUE(ExtsRV64G.at("f") == (RISCVISAUtils::ExtensionVersion{2, 2}));
275   EXPECT_TRUE(ExtsRV64G.at("d") == (RISCVISAUtils::ExtensionVersion{2, 2}));
276   EXPECT_TRUE(ExtsRV64G.at("zicsr") == (RISCVISAUtils::ExtensionVersion{2, 0}));
277   EXPECT_TRUE(ExtsRV64G.at("zifencei") ==
278               (RISCVISAUtils::ExtensionVersion{2, 0}));
279   EXPECT_TRUE(ExtsRV32G.at("zmmul") == (RISCVISAUtils::ExtensionVersion{1, 0}));
280   EXPECT_EQ(InfoRV64G.getXLen(), 64U);
281   EXPECT_EQ(InfoRV64G.getFLen(), 64U);
282   EXPECT_EQ(InfoRV64G.getMinVLen(), 0U);
283   EXPECT_EQ(InfoRV64G.getMaxELen(), 0U);
284   EXPECT_EQ(InfoRV64G.getMaxELenFp(), 0U);
285 
286   auto MaybeRV64GCV = RISCVISAInfo::parseArchString("rv64gcv", true);
287   ASSERT_THAT_EXPECTED(MaybeRV64GCV, Succeeded());
288   RISCVISAInfo &InfoRV64GCV = **MaybeRV64GCV;
289   const auto &ExtsRV64GCV = InfoRV64GCV.getExtensions();
290   EXPECT_EQ(ExtsRV64GCV.size(), 18UL);
291   EXPECT_TRUE(ExtsRV64GCV.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
292   EXPECT_TRUE(ExtsRV64GCV.at("m") == (RISCVISAUtils::ExtensionVersion{2, 0}));
293   EXPECT_TRUE(ExtsRV64GCV.at("a") == (RISCVISAUtils::ExtensionVersion{2, 1}));
294   EXPECT_TRUE(ExtsRV64GCV.at("f") == (RISCVISAUtils::ExtensionVersion{2, 2}));
295   EXPECT_TRUE(ExtsRV64GCV.at("d") == (RISCVISAUtils::ExtensionVersion{2, 2}));
296   EXPECT_TRUE(ExtsRV64GCV.at("c") == (RISCVISAUtils::ExtensionVersion{2, 0}));
297   EXPECT_TRUE(ExtsRV64GCV.at("zicsr") == (RISCVISAUtils::ExtensionVersion{2, 0}));
298   EXPECT_TRUE(ExtsRV64GCV.at("zifencei") ==
299               (RISCVISAUtils::ExtensionVersion{2, 0}));
300   EXPECT_TRUE(ExtsRV32G.at("zmmul") == (RISCVISAUtils::ExtensionVersion{1, 0}));
301   EXPECT_TRUE(ExtsRV64GCV.at("v") == (RISCVISAUtils::ExtensionVersion{1, 0}));
302   EXPECT_TRUE(ExtsRV64GCV.at("zve32x") == (RISCVISAUtils::ExtensionVersion{1, 0}));
303   EXPECT_TRUE(ExtsRV64GCV.at("zve32f") == (RISCVISAUtils::ExtensionVersion{1, 0}));
304   EXPECT_TRUE(ExtsRV64GCV.at("zve64x") == (RISCVISAUtils::ExtensionVersion{1, 0}));
305   EXPECT_TRUE(ExtsRV64GCV.at("zve64f") == (RISCVISAUtils::ExtensionVersion{1, 0}));
306   EXPECT_TRUE(ExtsRV64GCV.at("zve64d") == (RISCVISAUtils::ExtensionVersion{1, 0}));
307   EXPECT_TRUE(ExtsRV64GCV.at("zvl32b") == (RISCVISAUtils::ExtensionVersion{1, 0}));
308   EXPECT_TRUE(ExtsRV64GCV.at("zvl64b") == (RISCVISAUtils::ExtensionVersion{1, 0}));
309   EXPECT_TRUE(ExtsRV64GCV.at("zvl128b") == (RISCVISAUtils::ExtensionVersion{1, 0}));
310   EXPECT_EQ(InfoRV64GCV.getXLen(), 64U);
311   EXPECT_EQ(InfoRV64GCV.getFLen(), 64U);
312   EXPECT_EQ(InfoRV64GCV.getMinVLen(), 128U);
313   EXPECT_EQ(InfoRV64GCV.getMaxELen(), 64U);
314   EXPECT_EQ(InfoRV64GCV.getMaxELenFp(), 64U);
315 }
316 
317 TEST(ParseArchString, RejectsUnrecognizedExtensionNamesByDefault) {
318   EXPECT_EQ(
319       toString(
320           RISCVISAInfo::parseArchString("rv32i_zmadeup", true).takeError()),
321       "unsupported standard user-level extension 'zmadeup'");
322   EXPECT_EQ(
323       toString(
324           RISCVISAInfo::parseArchString("rv64g_smadeup", true).takeError()),
325       "unsupported standard supervisor-level extension 'smadeup'");
326   EXPECT_EQ(
327       toString(
328           RISCVISAInfo::parseArchString("rv64g_xmadeup", true).takeError()),
329       "unsupported non-standard user-level extension 'xmadeup'");
330   EXPECT_EQ(
331       toString(
332           RISCVISAInfo::parseArchString("rv32i_zmadeup1p0", true).takeError()),
333       "unsupported standard user-level extension 'zmadeup'");
334   EXPECT_EQ(
335       toString(
336           RISCVISAInfo::parseArchString("rv64g_smadeup1p0", true).takeError()),
337       "unsupported standard supervisor-level extension 'smadeup'");
338   EXPECT_EQ(
339       toString(
340           RISCVISAInfo::parseArchString("rv64g_xmadeup1p0", true).takeError()),
341       "unsupported non-standard user-level extension 'xmadeup'");
342 }
343 
344 TEST(ParseArchString, AcceptsVersionInLongOrShortForm) {
345   for (StringRef Input : {"rv64i2p1"}) {
346     auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true);
347     ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
348     const auto &Exts = (*MaybeISAInfo)->getExtensions();
349     EXPECT_TRUE(Exts.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
350   }
351   for (StringRef Input : {"rv32i_zfinx1", "rv32i_zfinx1p0"}) {
352     auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true);
353     ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
354     const auto &Exts = (*MaybeISAInfo)->getExtensions();
355     EXPECT_TRUE(Exts.at("zfinx") == (RISCVISAUtils::ExtensionVersion{1, 0}));
356   }
357 }
358 
359 TEST(ParseArchString, RejectsUnrecognizedExtensionVersionsByDefault) {
360   EXPECT_EQ(
361       toString(RISCVISAInfo::parseArchString("rv64i2p", true).takeError()),
362       "minor version number missing after 'p' for extension 'i'");
363   EXPECT_EQ(
364       toString(RISCVISAInfo::parseArchString("rv64i1p0", true).takeError()),
365       "unsupported version number 1.0 for extension 'i'");
366   EXPECT_EQ(
367       toString(RISCVISAInfo::parseArchString("rv64i9p9", true).takeError()),
368       "unsupported version number 9.9 for extension 'i'");
369   EXPECT_EQ(
370       toString(RISCVISAInfo::parseArchString("rv32im0p1", true).takeError()),
371       "unsupported version number 0.1 for extension 'm'");
372   EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv32izifencei10p10", true)
373                          .takeError()),
374             "unsupported version number 10.10 for extension 'zifencei'");
375 }
376 
377 TEST(ParseArchString, AcceptsUnderscoreSplittingExtensions) {
378   for (StringRef Input : {"rv32imafdczifencei", "rv32i_m_a_f_d_c_zifencei"}) {
379     auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true);
380     ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
381     const auto &Exts = (*MaybeISAInfo)->getExtensions();
382     EXPECT_EQ(Exts.size(), 9UL);
383     EXPECT_EQ(Exts.count("i"), 1U);
384     EXPECT_EQ(Exts.count("m"), 1U);
385     EXPECT_EQ(Exts.count("a"), 1U);
386     EXPECT_EQ(Exts.count("f"), 1U);
387     EXPECT_EQ(Exts.count("d"), 1U);
388     EXPECT_EQ(Exts.count("c"), 1U);
389     EXPECT_EQ(Exts.count("zicsr"), 1U);
390     EXPECT_EQ(Exts.count("zifencei"), 1U);
391     EXPECT_EQ(Exts.count("zmmul"), 1U);
392   }
393 }
394 
395 TEST(ParseArchString, AcceptsRelaxSingleLetterExtensions) {
396   for (StringRef Input :
397        {"rv32imfad", "rv32im_fa_d", "rv32im2p0fad", "rv32i2p1m2p0fad"}) {
398     auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true);
399     ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
400     const auto &Exts = (*MaybeISAInfo)->getExtensions();
401     EXPECT_EQ(Exts.size(), 7UL);
402     EXPECT_EQ(Exts.count("i"), 1U);
403     EXPECT_EQ(Exts.count("m"), 1U);
404     EXPECT_EQ(Exts.count("f"), 1U);
405     EXPECT_EQ(Exts.count("a"), 1U);
406     EXPECT_EQ(Exts.count("d"), 1U);
407     EXPECT_EQ(Exts.count("zicsr"), 1U);
408     EXPECT_EQ(Exts.count("zmmul"), 1U);
409   }
410 }
411 
412 TEST(ParseArchString, AcceptsRelaxMixedLetterExtensions) {
413   for (StringRef Input :
414        {"rv32i_zihintntl_m_a_f_d_svinval", "rv32izihintntl_mafdsvinval",
415         "rv32i_zihintntl_mafd_svinval"}) {
416     auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true);
417     ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
418     const auto &Exts = (*MaybeISAInfo)->getExtensions();
419     EXPECT_EQ(Exts.size(), 9UL);
420     EXPECT_EQ(Exts.count("i"), 1U);
421     EXPECT_EQ(Exts.count("m"), 1U);
422     EXPECT_EQ(Exts.count("a"), 1U);
423     EXPECT_EQ(Exts.count("f"), 1U);
424     EXPECT_EQ(Exts.count("d"), 1U);
425     EXPECT_EQ(Exts.count("zihintntl"), 1U);
426     EXPECT_EQ(Exts.count("svinval"), 1U);
427     EXPECT_EQ(Exts.count("zicsr"), 1U);
428     EXPECT_EQ(Exts.count("zmmul"), 1U);
429   }
430 }
431 
432 TEST(ParseArchString, AcceptsAmbiguousFromRelaxExtensions) {
433   for (StringRef Input : {"rv32i_zba_m", "rv32izba_m", "rv32izba1p0_m2p0"}) {
434     auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true);
435     ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
436     const auto &Exts = (*MaybeISAInfo)->getExtensions();
437     EXPECT_EQ(Exts.size(), 4UL);
438     EXPECT_EQ(Exts.count("i"), 1U);
439     EXPECT_EQ(Exts.count("zba"), 1U);
440     EXPECT_EQ(Exts.count("m"), 1U);
441     EXPECT_EQ(Exts.count("zmmul"), 1U);
442   }
443   for (StringRef Input :
444        {"rv32ia_zba_m", "rv32iazba_m", "rv32ia2p1zba1p0_m2p0"}) {
445     auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true);
446     ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
447     const auto &Exts = (*MaybeISAInfo)->getExtensions();
448     EXPECT_EQ(Exts.size(), 5UL);
449     EXPECT_EQ(Exts.count("i"), 1U);
450     EXPECT_EQ(Exts.count("zba"), 1U);
451     EXPECT_EQ(Exts.count("m"), 1U);
452     EXPECT_EQ(Exts.count("a"), 1U);
453     EXPECT_EQ(Exts.count("zmmul"), 1U);
454   }
455 }
456 
457 TEST(ParseArchString, RejectsRelaxExtensionsNotStartWithEorIorG) {
458   EXPECT_EQ(
459       toString(RISCVISAInfo::parseArchString("rv32zba_im", true).takeError()),
460       "first letter after 'rv32' should be 'e', 'i' or 'g'");
461 }
462 
463 TEST(ParseArchString,
464      RejectsMultiLetterExtensionFollowBySingleLetterExtensions) {
465   for (StringRef Input : {"rv32izbam", "rv32i_zbam"})
466     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
467               "unsupported standard user-level extension 'zbam'");
468   EXPECT_EQ(
469       toString(RISCVISAInfo::parseArchString("rv32izbai_m", true).takeError()),
470       "unsupported standard user-level extension 'zbai'");
471   EXPECT_EQ(
472       toString(RISCVISAInfo::parseArchString("rv32izbaim", true).takeError()),
473       "unsupported standard user-level extension 'zbaim'");
474   EXPECT_EQ(
475       toString(
476           RISCVISAInfo::parseArchString("rv32i_zba1p0m", true).takeError()),
477       "unsupported standard user-level extension 'zba1p0m'");
478 }
479 
480 TEST(ParseArchString, RejectsDoubleOrTrailingUnderscore) {
481   EXPECT_EQ(
482       toString(RISCVISAInfo::parseArchString("rv64i__m", true).takeError()),
483       "extension name missing after separator '_'");
484 
485   for (StringRef Input :
486        {"rv32ezicsr__zifencei", "rv32i_", "rv32izicsr_", "rv64im_"}) {
487     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
488               "extension name missing after separator '_'");
489   }
490 }
491 
492 TEST(ParseArchString, RejectsDuplicateExtensionNames) {
493   EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv64ii", true).takeError()),
494             "invalid standard user-level extension 'i'");
495   EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv32ee", true).takeError()),
496             "invalid standard user-level extension 'e'");
497   EXPECT_EQ(
498       toString(RISCVISAInfo::parseArchString("rv64imm", true).takeError()),
499       "duplicated standard user-level extension 'm'");
500   EXPECT_EQ(
501       toString(
502           RISCVISAInfo::parseArchString("rv32i_zicsr_zicsr", true).takeError()),
503       "duplicated standard user-level extension 'zicsr'");
504 }
505 
506 TEST(ParseArchString,
507      RejectsExperimentalExtensionsIfNotEnableExperimentalExtension) {
508   EXPECT_EQ(
509       toString(RISCVISAInfo::parseArchString("rv64izalasr", false).takeError()),
510       "requires '-menable-experimental-extensions' for experimental extension "
511       "'zalasr'");
512 }
513 
514 TEST(ParseArchString,
515      AcceptsExperimentalExtensionsIfEnableExperimentalExtension) {
516   // Note: If zalasr becomes none-experimental, this test will need
517   // updating (and unfortunately, it will still pass). The failure of
518   // RejectsExperimentalExtensionsIfNotEnableExperimentalExtension will
519   // hopefully serve as a reminder to update.
520   auto MaybeISAInfo = RISCVISAInfo::parseArchString("rv64izalasr", true, false);
521   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
522   const auto &Exts = (*MaybeISAInfo)->getExtensions();
523   EXPECT_EQ(Exts.size(), 2UL);
524   EXPECT_EQ(Exts.count("zalasr"), 1U);
525   auto MaybeISAInfo2 = RISCVISAInfo::parseArchString("rv64izalasr0p1", true);
526   ASSERT_THAT_EXPECTED(MaybeISAInfo2, Succeeded());
527   const auto &Exts2 = (*MaybeISAInfo2)->getExtensions();
528   EXPECT_EQ(Exts2.size(), 2UL);
529   EXPECT_EQ(Exts2.count("zalasr"), 1U);
530 }
531 
532 TEST(ParseArchString,
533      RequiresExplicitVersionNumberForExperimentalExtensionByDefault) {
534   EXPECT_EQ(
535       toString(RISCVISAInfo::parseArchString("rv64izalasr", true).takeError()),
536       "experimental extension requires explicit version number `zalasr`");
537 }
538 
539 TEST(ParseArchString,
540      AcceptsUnrecognizedVersionIfNotExperimentalExtensionVersionCheck) {
541   auto MaybeISAInfo =
542       RISCVISAInfo::parseArchString("rv64izalasr9p9", true, false);
543   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
544   const auto &Exts = (*MaybeISAInfo)->getExtensions();
545   EXPECT_EQ(Exts.size(), 2UL);
546   EXPECT_TRUE(Exts.at("zalasr") == (RISCVISAUtils::ExtensionVersion{9, 9}));
547 }
548 
549 TEST(ParseArchString, RejectsUnrecognizedVersionForExperimentalExtension) {
550   EXPECT_EQ(
551       toString(
552           RISCVISAInfo::parseArchString("rv64izalasr9p9", true).takeError()),
553       "unsupported version number 9.9 for experimental extension 'zalasr' "
554       "(this compiler supports 0.1)");
555 }
556 
557 TEST(ParseArchString, RejectsExtensionVersionForG) {
558   for (StringRef Input : {"rv32g1c", "rv64g2p0"}) {
559     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
560               "version not supported for 'g'");
561   }
562 }
563 
564 TEST(ParseArchString, AddsImpliedExtensions) {
565   // Does not attempt to exhaustively test all implications.
566   auto MaybeRV64ID = RISCVISAInfo::parseArchString("rv64id", true);
567   ASSERT_THAT_EXPECTED(MaybeRV64ID, Succeeded());
568   const auto &ExtsRV64ID = (*MaybeRV64ID)->getExtensions();
569   EXPECT_EQ(ExtsRV64ID.size(), 4UL);
570   EXPECT_EQ(ExtsRV64ID.count("i"), 1U);
571   EXPECT_EQ(ExtsRV64ID.count("f"), 1U);
572   EXPECT_EQ(ExtsRV64ID.count("d"), 1U);
573   EXPECT_EQ(ExtsRV64ID.count("zicsr"), 1U);
574 
575   auto MaybeRV32IZKN = RISCVISAInfo::parseArchString("rv64izkn", true);
576   ASSERT_THAT_EXPECTED(MaybeRV32IZKN, Succeeded());
577   const auto &ExtsRV32IZKN = (*MaybeRV32IZKN)->getExtensions();
578   EXPECT_EQ(ExtsRV32IZKN.size(), 8UL);
579   EXPECT_EQ(ExtsRV32IZKN.count("i"), 1U);
580   EXPECT_EQ(ExtsRV32IZKN.count("zbkb"), 1U);
581   EXPECT_EQ(ExtsRV32IZKN.count("zbkc"), 1U);
582   EXPECT_EQ(ExtsRV32IZKN.count("zbkx"), 1U);
583   EXPECT_EQ(ExtsRV32IZKN.count("zkne"), 1U);
584   EXPECT_EQ(ExtsRV32IZKN.count("zknd"), 1U);
585   EXPECT_EQ(ExtsRV32IZKN.count("zknh"), 1U);
586   EXPECT_EQ(ExtsRV32IZKN.count("zkn"), 1U);
587 }
588 
589 TEST(ParseArchString, RejectsConflictingExtensions) {
590   for (StringRef Input : {"rv32ifzfinx", "rv64gzdinx"}) {
591     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
592               "'f' and 'zfinx' extensions are incompatible");
593   }
594 
595   for (StringRef Input : {"rv32idc_zcmp1p0", "rv64idc_zcmp1p0"}) {
596     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
597               "'zcmp' extension is incompatible with 'c' extension when 'd' "
598               "extension is enabled");
599   }
600 
601   for (StringRef Input : {"rv32id_zcd1p0_zcmp1p0", "rv64id_zcd1p0_zcmp1p0"}) {
602     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
603               "'zcmp' extension is incompatible with 'zcd' extension when 'd' "
604               "extension is enabled");
605   }
606 
607   for (StringRef Input : {"rv32idc_zcmt1p0", "rv64idc_zcmt1p0"}) {
608     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
609               "'zcmt' extension is incompatible with 'c' extension when 'd' "
610               "extension is enabled");
611   }
612 
613   for (StringRef Input : {"rv32id_zcd1p0_zcmt1p0", "rv64id_zcd1p0_zcmt1p0"}) {
614     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
615               "'zcmt' extension is incompatible with 'zcd' extension when 'd' "
616               "extension is enabled");
617   }
618 
619   for (StringRef Input : {"rv64if_zcf"}) {
620     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
621               "'zcf' is only supported for 'rv32'");
622   }
623 
624   for (StringRef Input : {"rv64i_xwchc"}) {
625     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
626               "'Xwchc' is only supported for 'rv32'");
627   }
628 
629   for (StringRef Input : {"rv32id_xwchc"}) {
630     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
631               "'D' and 'Xwchc' extensions are incompatible");
632   }
633 
634   for (StringRef Input : {"rv32i_zcb_xwchc"}) {
635     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
636               "'Xwchc' and 'Zcb' extensions are incompatible");
637   }
638 }
639 
640 TEST(ParseArchString, MissingDepency) {
641   for (StringRef Input : {"rv32i_zvl32b", "rv64i_zvl128b"}) {
642     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
643               "'zvl*b' requires 'v' or 'zve*' extension to also be specified");
644   }
645 
646   for (StringRef Input : {"rv32i_zvbb"}) {
647     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
648               "'zvbb' requires 'v' or 'zve*' extension to also be specified");
649   }
650 
651   for (StringRef Input : {"rv32i_zvbc32e0p7"}) {
652     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
653               "'zvbc32e' requires 'v' or 'zve*' extension to also be specified");
654   }
655 
656   for (StringRef Input : {"rv32i_zvbc"}) {
657     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
658               "'zvbc' requires 'v' or 'zve64*' extension to also be specified");
659   }
660 
661   for (StringRef Input : {"rv32i_zvkb"}) {
662     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
663               "'zvkb' requires 'v' or 'zve*' extension to also be specified");
664   }
665 
666   for (StringRef Input : {"rv32i_zvkg"}) {
667     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
668               "'zvkg' requires 'v' or 'zve*' extension to also be specified");
669   }
670 
671   for (StringRef Input : {"rv32i_zvkgs0p7"}) {
672     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
673               "'zvkg' requires 'v' or 'zve*' extension to also be specified");
674   }
675 
676   for (StringRef Input : {"rv32i_zvkned"}) {
677     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
678               "'zvkned' requires 'v' or 'zve*' extension to also be specified");
679   }
680 
681   for (StringRef Input : {"rv32i_zvknha"}) {
682     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
683               "'zvknha' requires 'v' or 'zve*' extension to also be specified");
684   }
685 
686   for (StringRef Input : {"rv32i_zvksed"}) {
687     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
688               "'zvksed' requires 'v' or 'zve*' extension to also be specified");
689   }
690 
691   for (StringRef Input : {"rv32i_zvksh"}) {
692     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
693               "'zvksh' requires 'v' or 'zve*' extension to also be specified");
694   }
695 
696   for (StringRef Input : {"rv32i_zvknhb"}) {
697     EXPECT_EQ(
698         toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
699         "'zvknhb' requires 'v' or 'zve64*' extension to also be specified");
700   }
701 
702   for (StringRef Input : {"rv32i_zacas1p0"}) {
703     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
704               "'zacas' requires 'a' or 'zaamo' extension to also be specified");
705   }
706 
707   for (StringRef Input : {"rv32i_zabha"}) {
708     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
709               "'zabha' requires 'a' or 'zaamo' extension to also be specified");
710   }
711 }
712 
713 TEST(ParseArchString, RejectsUnrecognizedProfileNames) {
714   for (StringRef Input : {"rvi23u99", "rvz23u64", "rva99u32"}) {
715     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
716               "string must begin with rv32{i,e,g}, rv64{i,e,g}, or a supported "
717               "profile name");
718   }
719 }
720 
721 TEST(ParseArchString, RejectsProfilesWithUnseparatedExtraExtensions) {
722   for (StringRef Input : {"rvi20u32m", "rvi20u64c"}) {
723     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
724               "additional extensions must be after separator '_'");
725   }
726 }
727 
728 TEST(ParseArchString, AcceptsBareProfileNames) {
729   auto MaybeRVA20U64 = RISCVISAInfo::parseArchString("rva20u64", true);
730   ASSERT_THAT_EXPECTED(MaybeRVA20U64, Succeeded());
731   const auto &Exts = (*MaybeRVA20U64)->getExtensions();
732   EXPECT_EQ(Exts.size(), 14UL);
733   EXPECT_EQ(Exts.count("i"), 1U);
734   EXPECT_EQ(Exts.count("m"), 1U);
735   EXPECT_EQ(Exts.count("f"), 1U);
736   EXPECT_EQ(Exts.count("a"), 1U);
737   EXPECT_EQ(Exts.count("d"), 1U);
738   EXPECT_EQ(Exts.count("c"), 1U);
739   EXPECT_EQ(Exts.count("za128rs"), 1U);
740   EXPECT_EQ(Exts.count("zicntr"), 1U);
741   EXPECT_EQ(Exts.count("ziccif"), 1U);
742   EXPECT_EQ(Exts.count("zicsr"), 1U);
743   EXPECT_EQ(Exts.count("ziccrse"), 1U);
744   EXPECT_EQ(Exts.count("ziccamoa"), 1U);
745   EXPECT_EQ(Exts.count("zicclsm"), 1U);
746   EXPECT_EQ(Exts.count("zmmul"), 1U);
747 
748   auto MaybeRVA23U64 = RISCVISAInfo::parseArchString("rva23u64", true);
749   ASSERT_THAT_EXPECTED(MaybeRVA23U64, Succeeded());
750   EXPECT_GT((*MaybeRVA23U64)->getExtensions().size(), 13UL);
751 }
752 
753 TEST(ParseArchSTring, AcceptsProfileNamesWithSeparatedAdditionalExtensions) {
754   auto MaybeRVI20U64 = RISCVISAInfo::parseArchString("rvi20u64_m_zba", true);
755   ASSERT_THAT_EXPECTED(MaybeRVI20U64, Succeeded());
756   const auto &Exts = (*MaybeRVI20U64)->getExtensions();
757   EXPECT_EQ(Exts.size(), 4UL);
758   EXPECT_EQ(Exts.count("i"), 1U);
759   EXPECT_EQ(Exts.count("m"), 1U);
760   EXPECT_EQ(Exts.count("zba"), 1U);
761   EXPECT_EQ(Exts.count("zmmul"), 1U);
762 }
763 
764 TEST(ParseArchString,
765      RejectsProfilesWithAdditionalExtensionsGivenAlreadyInProfile) {
766   // This test was added to document the current behaviour. Discussion isn't
767   // believed to have taken place about if this is desirable or not.
768   EXPECT_EQ(
769       toString(
770           RISCVISAInfo::parseArchString("rva20u64_zicntr", true).takeError()),
771       "duplicated standard user-level extension 'zicntr'");
772 }
773 
774 TEST(ParseArchString,
775      RejectsExperimentalProfilesIfEnableExperimentalExtensionsNotSet) {
776   EXPECT_EQ(
777       toString(RISCVISAInfo::parseArchString("rva23u64", false).takeError()),
778       "requires '-menable-experimental-extensions' for profile 'rva23u64'");
779 }
780 
781 TEST(ToFeatures, IIsDroppedAndExperimentalExtensionsArePrefixed) {
782   auto MaybeISAInfo1 =
783       RISCVISAInfo::parseArchString("rv64im_zalasr", true, false);
784   ASSERT_THAT_EXPECTED(MaybeISAInfo1, Succeeded());
785   EXPECT_THAT((*MaybeISAInfo1)->toFeatures(),
786               ElementsAre("+m", "+zmmul", "+experimental-zalasr"));
787 
788   auto MaybeISAInfo2 = RISCVISAInfo::parseArchString(
789       "rv32e_zalasr_xventanacondops", true, false);
790   ASSERT_THAT_EXPECTED(MaybeISAInfo2, Succeeded());
791   EXPECT_THAT((*MaybeISAInfo2)->toFeatures(),
792               ElementsAre("+e", "+experimental-zalasr", "+xventanacondops"));
793 }
794 
795 TEST(ToFeatures, UnsupportedExtensionsAreDropped) {
796   auto MaybeISAInfo =
797       RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0_xmadeup1p0");
798   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
799   EXPECT_THAT((*MaybeISAInfo)->toFeatures(), ElementsAre("+m"));
800 }
801 
802 TEST(ToFeatures, UnsupportedExtensionsAreKeptIfIgnoreUnknownIsFalse) {
803   auto MaybeISAInfo =
804       RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0_xmadeup1p0");
805   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
806   EXPECT_THAT((*MaybeISAInfo)->toFeatures(false, false),
807               ElementsAre("+m", "+xmadeup"));
808 }
809 
810 TEST(ToFeatures, AddAllExtensionsAddsNegativeExtensions) {
811   auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0");
812   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
813 
814   auto Features = (*MaybeISAInfo)->toFeatures(true);
815   EXPECT_GT(Features.size(), 1UL);
816   EXPECT_EQ(Features.front(), "+m");
817   // Every feature after should be a negative feature
818   for (auto &NegativeExt : llvm::drop_begin(Features))
819     EXPECT_TRUE(NegativeExt.substr(0, 1) == "-");
820 }
821 
822 TEST(OrderedExtensionMap, ExtensionsAreCorrectlyOrdered) {
823   RISCVISAUtils::OrderedExtensionMap Exts;
824   for (auto ExtName : {"y", "l", "m", "c", "i", "xfoo", "xbar", "sfoo", "sbar",
825                        "zmfoo", "zzfoo", "zfinx", "zicsr"})
826     Exts[ExtName] = {1, 0};
827 
828   std::vector<std::string> ExtNames;
829   for (const auto &Ext : Exts)
830     ExtNames.push_back(Ext.first);
831 
832   // FIXME: 'l' and 'y' should be ordered after 'i', 'm', 'c'.
833   EXPECT_THAT(ExtNames,
834               ElementsAre("i", "m", "l", "c", "y", "zicsr", "zmfoo", "zfinx",
835                            "zzfoo", "sbar", "sfoo", "xbar", "xfoo"));
836 }
837 
838 TEST(ParseArchString, ZceImplication) {
839   auto MaybeRV32IZce = RISCVISAInfo::parseArchString("rv32izce", true);
840   ASSERT_THAT_EXPECTED(MaybeRV32IZce, Succeeded());
841   const auto &ExtsRV32IZce = (*MaybeRV32IZce)->getExtensions();
842   EXPECT_EQ(ExtsRV32IZce.size(), 7UL);
843   EXPECT_EQ(ExtsRV32IZce.count("i"), 1U);
844   EXPECT_EQ(ExtsRV32IZce.count("zicsr"), 1U);
845   EXPECT_EQ(ExtsRV32IZce.count("zca"), 1U);
846   EXPECT_EQ(ExtsRV32IZce.count("zcb"), 1U);
847   EXPECT_EQ(ExtsRV32IZce.count("zce"), 1U);
848   EXPECT_EQ(ExtsRV32IZce.count("zcmp"), 1U);
849   EXPECT_EQ(ExtsRV32IZce.count("zcmt"), 1U);
850 
851   auto MaybeRV32IFZce = RISCVISAInfo::parseArchString("rv32ifzce", true);
852   ASSERT_THAT_EXPECTED(MaybeRV32IFZce, Succeeded());
853   const auto &ExtsRV32IFZce = (*MaybeRV32IFZce)->getExtensions();
854   EXPECT_EQ(ExtsRV32IFZce.size(), 9UL);
855   EXPECT_EQ(ExtsRV32IFZce.count("i"), 1U);
856   EXPECT_EQ(ExtsRV32IFZce.count("zicsr"), 1U);
857   EXPECT_EQ(ExtsRV32IFZce.count("f"), 1U);
858   EXPECT_EQ(ExtsRV32IFZce.count("zca"), 1U);
859   EXPECT_EQ(ExtsRV32IFZce.count("zcb"), 1U);
860   EXPECT_EQ(ExtsRV32IFZce.count("zce"), 1U);
861   EXPECT_EQ(ExtsRV32IFZce.count("zcf"), 1U);
862   EXPECT_EQ(ExtsRV32IFZce.count("zcmp"), 1U);
863   EXPECT_EQ(ExtsRV32IFZce.count("zcmt"), 1U);
864 
865   auto MaybeRV32IDZce = RISCVISAInfo::parseArchString("rv32idzce", true);
866   ASSERT_THAT_EXPECTED(MaybeRV32IDZce, Succeeded());
867   const auto &ExtsRV32IDZce = (*MaybeRV32IDZce)->getExtensions();
868   EXPECT_EQ(ExtsRV32IDZce.size(), 10UL);
869   EXPECT_EQ(ExtsRV32IDZce.count("i"), 1U);
870   EXPECT_EQ(ExtsRV32IDZce.count("zicsr"), 1U);
871   EXPECT_EQ(ExtsRV32IDZce.count("f"), 1U);
872   EXPECT_EQ(ExtsRV32IDZce.count("d"), 1U);
873   EXPECT_EQ(ExtsRV32IDZce.count("zca"), 1U);
874   EXPECT_EQ(ExtsRV32IDZce.count("zcb"), 1U);
875   EXPECT_EQ(ExtsRV32IDZce.count("zce"), 1U);
876   EXPECT_EQ(ExtsRV32IDZce.count("zcf"), 1U);
877   EXPECT_EQ(ExtsRV32IDZce.count("zcmp"), 1U);
878   EXPECT_EQ(ExtsRV32IDZce.count("zcmt"), 1U);
879 
880   auto MaybeRV64IZce = RISCVISAInfo::parseArchString("rv64izce", true);
881   ASSERT_THAT_EXPECTED(MaybeRV64IZce, Succeeded());
882   const auto &ExtsRV64IZce = (*MaybeRV64IZce)->getExtensions();
883   EXPECT_EQ(ExtsRV64IZce.size(), 7UL);
884   EXPECT_EQ(ExtsRV64IZce.count("i"), 1U);
885   EXPECT_EQ(ExtsRV64IZce.count("zicsr"), 1U);
886   EXPECT_EQ(ExtsRV64IZce.count("zca"), 1U);
887   EXPECT_EQ(ExtsRV64IZce.count("zcb"), 1U);
888   EXPECT_EQ(ExtsRV64IZce.count("zce"), 1U);
889   EXPECT_EQ(ExtsRV64IZce.count("zcmp"), 1U);
890   EXPECT_EQ(ExtsRV64IZce.count("zcmt"), 1U);
891 
892   auto MaybeRV64IFZce = RISCVISAInfo::parseArchString("rv64ifzce", true);
893   ASSERT_THAT_EXPECTED(MaybeRV64IFZce, Succeeded());
894   const auto &ExtsRV64IFZce = (*MaybeRV64IFZce)->getExtensions();
895   EXPECT_EQ(ExtsRV64IFZce.size(), 8UL);
896   EXPECT_EQ(ExtsRV64IFZce.count("i"), 1U);
897   EXPECT_EQ(ExtsRV64IFZce.count("zicsr"), 1U);
898   EXPECT_EQ(ExtsRV64IFZce.count("f"), 1U);
899   EXPECT_EQ(ExtsRV64IFZce.count("zca"), 1U);
900   EXPECT_EQ(ExtsRV64IFZce.count("zcb"), 1U);
901   EXPECT_EQ(ExtsRV64IFZce.count("zce"), 1U);
902   EXPECT_EQ(ExtsRV64IFZce.count("zcmp"), 1U);
903   EXPECT_EQ(ExtsRV64IFZce.count("zcmt"), 1U);
904 
905   EXPECT_EQ(ExtsRV64IFZce.count("zca"), 1U);
906   EXPECT_EQ(ExtsRV64IFZce.count("zcb"), 1U);
907   EXPECT_EQ(ExtsRV64IFZce.count("zce"), 1U);
908   EXPECT_EQ(ExtsRV64IFZce.count("zcmp"), 1U);
909   EXPECT_EQ(ExtsRV64IFZce.count("zcmt"), 1U);
910 
911   auto MaybeRV64IDZce = RISCVISAInfo::parseArchString("rv64idzce", true);
912   ASSERT_THAT_EXPECTED(MaybeRV64IDZce, Succeeded());
913   const auto &ExtsRV64IDZce = (*MaybeRV64IDZce)->getExtensions();
914   EXPECT_EQ(ExtsRV64IDZce.size(), 9UL);
915   EXPECT_EQ(ExtsRV64IDZce.count("i"), 1U);
916   EXPECT_EQ(ExtsRV64IDZce.count("zicsr"), 1U);
917   EXPECT_EQ(ExtsRV64IDZce.count("f"), 1U);
918   EXPECT_EQ(ExtsRV64IDZce.count("d"), 1U);
919   EXPECT_EQ(ExtsRV64IDZce.count("zca"), 1U);
920   EXPECT_EQ(ExtsRV64IDZce.count("zcb"), 1U);
921   EXPECT_EQ(ExtsRV64IDZce.count("zce"), 1U);
922   EXPECT_EQ(ExtsRV64IDZce.count("zcmp"), 1U);
923   EXPECT_EQ(ExtsRV64IDZce.count("zcmt"), 1U);
924 }
925 
926 TEST(isSupportedExtensionWithVersion, AcceptsSingleExtensionWithVersion) {
927   EXPECT_TRUE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb1p0"));
928   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb"));
929   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo1p0"));
930   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo"));
931   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion(""));
932   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("c2p0zbb1p0"));
933 }
934 
935 TEST(getTargetFeatureForExtension, RetrieveTargetFeatureFromOneExt) {
936   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbb"), "zbb");
937   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso1p0"), "ztso");
938   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso"), "ztso");
939   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zihintntl1234p4321"),
940             "");
941   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zfoo"), "");
942   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension(""), "");
943   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbbzihintntl"), "");
944 }
945 
946 TEST(RiscvExtensionsHelp, CheckExtensions) {
947   // clang-format off
948   std::string ExpectedOutput =
949 R"(All available -march extensions for RISC-V
950 
951     Name                 Version   Description
952     i                    2.1       This is a long dummy description
953     e                    2.0
954     m                    2.0
955     a                    2.1
956     f                    2.2
957     d                    2.2
958     c                    2.0
959     b                    1.0
960     v                    1.0
961     h                    1.0
962     zic64b               1.0
963     zicbom               1.0
964     zicbop               1.0
965     zicboz               1.0
966     ziccamoa             1.0
967     ziccif               1.0
968     zicclsm              1.0
969     ziccrse              1.0
970     zicntr               2.0
971     zicond               1.0
972     zicsr                2.0
973     zifencei             2.0
974     zihintntl            1.0
975     zihintpause          2.0
976     zihpm                2.0
977     zimop                1.0
978     zmmul                1.0
979     za128rs              1.0
980     za64rs               1.0
981     zaamo                1.0
982     zabha                1.0
983     zalrsc               1.0
984     zama16b              1.0
985     zawrs                1.0
986     zfa                  1.0
987     zfbfmin              1.0
988     zfh                  1.0
989     zfhmin               1.0
990     zfinx                1.0
991     zdinx                1.0
992     zca                  1.0
993     zcb                  1.0
994     zcd                  1.0
995     zce                  1.0
996     zcf                  1.0
997     zcmop                1.0
998     zcmp                 1.0
999     zcmt                 1.0
1000     zba                  1.0
1001     zbb                  1.0
1002     zbc                  1.0
1003     zbkb                 1.0
1004     zbkc                 1.0
1005     zbkx                 1.0
1006     zbs                  1.0
1007     zk                   1.0
1008     zkn                  1.0
1009     zknd                 1.0
1010     zkne                 1.0
1011     zknh                 1.0
1012     zkr                  1.0
1013     zks                  1.0
1014     zksed                1.0
1015     zksh                 1.0
1016     zkt                  1.0
1017     ztso                 1.0
1018     zvbb                 1.0
1019     zvbc                 1.0
1020     zve32f               1.0
1021     zve32x               1.0
1022     zve64d               1.0
1023     zve64f               1.0
1024     zve64x               1.0
1025     zvfbfmin             1.0
1026     zvfbfwma             1.0
1027     zvfh                 1.0
1028     zvfhmin              1.0
1029     zvkb                 1.0
1030     zvkg                 1.0
1031     zvkn                 1.0
1032     zvknc                1.0
1033     zvkned               1.0
1034     zvkng                1.0
1035     zvknha               1.0
1036     zvknhb               1.0
1037     zvks                 1.0
1038     zvksc                1.0
1039     zvksed               1.0
1040     zvksg                1.0
1041     zvksh                1.0
1042     zvkt                 1.0
1043     zvl1024b             1.0
1044     zvl128b              1.0
1045     zvl16384b            1.0
1046     zvl2048b             1.0
1047     zvl256b              1.0
1048     zvl32768b            1.0
1049     zvl32b               1.0
1050     zvl4096b             1.0
1051     zvl512b              1.0
1052     zvl64b               1.0
1053     zvl65536b            1.0
1054     zvl8192b             1.0
1055     zhinx                1.0
1056     zhinxmin             1.0
1057     shcounterenw         1.0
1058     shgatpa              1.0
1059     shtvala              1.0
1060     shvsatpa             1.0
1061     shvstvala            1.0
1062     shvstvecd            1.0
1063     smaia                1.0
1064     smcdeleg             1.0
1065     smcsrind             1.0
1066     smepmp               1.0
1067     smstateen            1.0
1068     ssaia                1.0
1069     ssccfg               1.0
1070     ssccptr              1.0
1071     sscofpmf             1.0
1072     sscounterenw         1.0
1073     sscsrind             1.0
1074     ssstateen            1.0
1075     ssstrict             1.0
1076     sstc                 1.0
1077     sstvala              1.0
1078     sstvecd              1.0
1079     ssu64xl              1.0
1080     svade                1.0
1081     svadu                1.0
1082     svbare               1.0
1083     svinval              1.0
1084     svnapot              1.0
1085     svpbmt               1.0
1086     xcvalu               1.0
1087     xcvbi                1.0
1088     xcvbitmanip          1.0
1089     xcvelw               1.0
1090     xcvmac               1.0
1091     xcvmem               1.0
1092     xcvsimd              1.0
1093     xsfcease             1.0
1094     xsfvcp               1.0
1095     xsfvfnrclipxfqf      1.0
1096     xsfvfwmaccqqq        1.0
1097     xsfvqmaccdod         1.0
1098     xsfvqmaccqoq         1.0
1099     xsifivecdiscarddlone 1.0
1100     xsifivecflushdlone   1.0
1101     xtheadba             1.0
1102     xtheadbb             1.0
1103     xtheadbs             1.0
1104     xtheadcmo            1.0
1105     xtheadcondmov        1.0
1106     xtheadfmemidx        1.0
1107     xtheadmac            1.0
1108     xtheadmemidx         1.0
1109     xtheadmempair        1.0
1110     xtheadsync           1.0
1111     xtheadvdot           1.0
1112     xventanacondops      1.0
1113     xwchc                2.2
1114 
1115 Experimental extensions
1116     zicfilp              1.0       This is a long dummy description
1117     zicfiss              1.0
1118     zacas                1.0
1119     zalasr               0.1
1120     zvbc32e              0.7
1121     zvkgs                0.7
1122     smmpm                1.0
1123     smnpm                1.0
1124     ssnpm                1.0
1125     sspm                 1.0
1126     ssqosid              1.0
1127     supm                 1.0
1128 
1129 Supported Profiles
1130     rva20s64
1131     rva20u64
1132     rva22s64
1133     rva22u64
1134     rvi20u32
1135     rvi20u64
1136 
1137 Experimental Profiles
1138     rva23s64
1139     rva23u64
1140     rvb23s64
1141     rvb23u64
1142     rvm23u32
1143 
1144 Use -march to specify the target's extension.
1145 For example, clang -march=rv32i_v1p0)";
1146   // clang-format on
1147 
1148   StringMap<StringRef> DummyMap;
1149   DummyMap["i"] = "This is a long dummy description";
1150   DummyMap["experimental-zicfilp"] = "This is a long dummy description";
1151 
1152   outs().flush();
1153   testing::internal::CaptureStdout();
1154   RISCVISAInfo::printSupportedExtensions(DummyMap);
1155   outs().flush();
1156 
1157   std::string CapturedOutput = testing::internal::GetCapturedStdout();
1158   EXPECT_TRUE([](std::string &Captured, std::string &Expected) {
1159                 return Captured.find(Expected) != std::string::npos;
1160               }(CapturedOutput, ExpectedOutput));
1161 }
1162 
1163 TEST(TargetParserTest, RISCVPrintEnabledExtensions) {
1164   // clang-format off
1165   std::string ExpectedOutput =
1166 R"(Extensions enabled for the given RISC-V target
1167 
1168     Name                 Version   Description
1169     i                    2.1       'I' (Base Integer Instruction Set)
1170 
1171 Experimental extensions
1172     zicfilp              1.0       'Zicfilp' (Landing pad)
1173 
1174 ISA String: rv64i2p1_zicfilp1p0_zicsr2p0
1175 )";
1176   // clang-format on
1177 
1178   StringMap<StringRef> DescMap;
1179   DescMap["i"] = "'I' (Base Integer Instruction Set)";
1180   DescMap["experimental-zicfilp"] = "'Zicfilp' (Landing pad)";
1181   std::set<StringRef> EnabledExtensions = {"i", "experimental-zicfilp"};
1182 
1183   outs().flush();
1184   testing::internal::CaptureStdout();
1185   RISCVISAInfo::printEnabledExtensions(/*IsRV64=*/true, EnabledExtensions,
1186                                        DescMap);
1187   outs().flush();
1188   std::string CapturedOutput = testing::internal::GetCapturedStdout();
1189 
1190   EXPECT_EQ(CapturedOutput, ExpectedOutput);
1191 }
1192