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