xref: /llvm-project/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (revision 891d687137ad9bb3b4efae116f9539addb5be0ea)
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     zacas                1.0
938     zama16b              1.0
939     zawrs                1.0
940     zfa                  1.0
941     zfh                  1.0
942     zfhmin               1.0
943     zfinx                1.0
944     zdinx                1.0
945     zca                  1.0
946     zcb                  1.0
947     zcd                  1.0
948     zce                  1.0
949     zcf                  1.0
950     zcmop                1.0
951     zcmp                 1.0
952     zcmt                 1.0
953     zba                  1.0
954     zbb                  1.0
955     zbc                  1.0
956     zbkb                 1.0
957     zbkc                 1.0
958     zbkx                 1.0
959     zbs                  1.0
960     zk                   1.0
961     zkn                  1.0
962     zknd                 1.0
963     zkne                 1.0
964     zknh                 1.0
965     zkr                  1.0
966     zks                  1.0
967     zksed                1.0
968     zksh                 1.0
969     zkt                  1.0
970     zvbb                 1.0
971     zvbc                 1.0
972     zve32f               1.0
973     zve32x               1.0
974     zve64d               1.0
975     zve64f               1.0
976     zve64x               1.0
977     zvfh                 1.0
978     zvfhmin              1.0
979     zvkb                 1.0
980     zvkg                 1.0
981     zvkn                 1.0
982     zvknc                1.0
983     zvkned               1.0
984     zvkng                1.0
985     zvknha               1.0
986     zvknhb               1.0
987     zvks                 1.0
988     zvksc                1.0
989     zvksed               1.0
990     zvksg                1.0
991     zvksh                1.0
992     zvkt                 1.0
993     zvl1024b             1.0
994     zvl128b              1.0
995     zvl16384b            1.0
996     zvl2048b             1.0
997     zvl256b              1.0
998     zvl32768b            1.0
999     zvl32b               1.0
1000     zvl4096b             1.0
1001     zvl512b              1.0
1002     zvl64b               1.0
1003     zvl65536b            1.0
1004     zvl8192b             1.0
1005     zhinx                1.0
1006     zhinxmin             1.0
1007     shcounterenw         1.0
1008     shgatpa              1.0
1009     shtvala              1.0
1010     shvsatpa             1.0
1011     shvstvala            1.0
1012     shvstvecd            1.0
1013     smaia                1.0
1014     smepmp               1.0
1015     smstateen            1.0
1016     ssaia                1.0
1017     ssccptr              1.0
1018     sscofpmf             1.0
1019     sscounterenw         1.0
1020     ssstateen            1.0
1021     ssstrict             1.0
1022     sstc                 1.0
1023     sstvala              1.0
1024     sstvecd              1.0
1025     ssu64xl              1.0
1026     svade                1.0
1027     svadu                1.0
1028     svbare               1.0
1029     svinval              1.0
1030     svnapot              1.0
1031     svpbmt               1.0
1032     xcvalu               1.0
1033     xcvbi                1.0
1034     xcvbitmanip          1.0
1035     xcvelw               1.0
1036     xcvmac               1.0
1037     xcvmem               1.0
1038     xcvsimd              1.0
1039     xsfcease             1.0
1040     xsfvcp               1.0
1041     xsfvfnrclipxfqf      1.0
1042     xsfvfwmaccqqq        1.0
1043     xsfvqmaccdod         1.0
1044     xsfvqmaccqoq         1.0
1045     xsifivecdiscarddlone 1.0
1046     xsifivecflushdlone   1.0
1047     xtheadba             1.0
1048     xtheadbb             1.0
1049     xtheadbs             1.0
1050     xtheadcmo            1.0
1051     xtheadcondmov        1.0
1052     xtheadfmemidx        1.0
1053     xtheadmac            1.0
1054     xtheadmemidx         1.0
1055     xtheadmempair        1.0
1056     xtheadsync           1.0
1057     xtheadvdot           1.0
1058     xventanacondops      1.0
1059 
1060 Experimental extensions
1061     zicfilp              0.4       This is a long dummy description
1062     zicfiss              0.4
1063     zaamo                0.2
1064     zabha                1.0
1065     zalasr               0.1
1066     zalrsc               0.2
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