xref: /llvm-project/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (revision 0cb7636a462a8d4209e2b6344304eb43f02853eb)
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   for (StringRef Input :
657        {"rv64i_xqcisls0p2", "rv64i_xqcia0p2", "rv64i_xqciac0p3",
658         "rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcicm0p2",
659         "rv64i_xqcics0p2", "rv64i_xqcicli0p2", "rv64i_xqciint0p2",
660         "rv64i_xqcilo0p2"}) {
661     EXPECT_THAT(
662         toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
663         ::testing::EndsWith(" is only supported for 'rv32'"));
664   }
665 }
666 
667 TEST(ParseArchString, MissingDepency) {
668   for (StringRef Input : {"rv32i_zvl32b", "rv64i_zvl128b"}) {
669     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
670               "'zvl*b' requires 'v' or 'zve*' extension to also be specified");
671   }
672 
673   // These all have an implication relationship, thus should pass
674   for (StringRef Input : {
675            "rv32i_zvbb",
676            "rv32i_zvbc32e0p7",
677            "rv32i_zvbc",
678            "rv32i_zvkb",
679            "rv32i_zvkg",
680            "rv32i_zvkgs0p7",
681            "rv32i_zvkned",
682            "rv32i_zvknha",
683            "rv32i_zvksed",
684            "rv32i_zvksh",
685            "rv32i_zvknhb",
686        }) {
687     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
688               "");
689   }
690 }
691 
692 TEST(ParseArchString, RejectsUnrecognizedProfileNames) {
693   for (StringRef Input : {"rvi23u99", "rvz23u64", "rva99u32"}) {
694     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
695               "string must begin with rv32{i,e,g}, rv64{i,e,g}, or a supported "
696               "profile name");
697   }
698 }
699 
700 TEST(ParseArchString, RejectsProfilesWithUnseparatedExtraExtensions) {
701   for (StringRef Input : {"rvi20u32m", "rvi20u64c"}) {
702     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
703               "additional extensions must be after separator '_'");
704   }
705 }
706 
707 TEST(ParseArchString, AcceptsBareProfileNames) {
708   auto MaybeRVA20U64 = RISCVISAInfo::parseArchString("rva20u64", true);
709   ASSERT_THAT_EXPECTED(MaybeRVA20U64, Succeeded());
710   const auto &Exts = (*MaybeRVA20U64)->getExtensions();
711   EXPECT_EQ(Exts.size(), 16UL);
712   EXPECT_EQ(Exts.count("i"), 1U);
713   EXPECT_EQ(Exts.count("m"), 1U);
714   EXPECT_EQ(Exts.count("f"), 1U);
715   EXPECT_EQ(Exts.count("a"), 1U);
716   EXPECT_EQ(Exts.count("d"), 1U);
717   EXPECT_EQ(Exts.count("c"), 1U);
718   EXPECT_EQ(Exts.count("za128rs"), 1U);
719   EXPECT_EQ(Exts.count("zicntr"), 1U);
720   EXPECT_EQ(Exts.count("ziccif"), 1U);
721   EXPECT_EQ(Exts.count("zicsr"), 1U);
722   EXPECT_EQ(Exts.count("ziccrse"), 1U);
723   EXPECT_EQ(Exts.count("ziccamoa"), 1U);
724   EXPECT_EQ(Exts.count("zicclsm"), 1U);
725   EXPECT_EQ(Exts.count("zmmul"), 1U);
726   EXPECT_EQ(Exts.count("zaamo"), 1U);
727   EXPECT_EQ(Exts.count("zalrsc"), 1U);
728 
729   auto MaybeRVA23U64 = RISCVISAInfo::parseArchString("rva23u64", true);
730   ASSERT_THAT_EXPECTED(MaybeRVA23U64, Succeeded());
731   EXPECT_GT((*MaybeRVA23U64)->getExtensions().size(), 13UL);
732 }
733 
734 TEST(ParseArchSTring, AcceptsProfileNamesWithSeparatedAdditionalExtensions) {
735   auto MaybeRVI20U64 = RISCVISAInfo::parseArchString("rvi20u64_m_zba", true);
736   ASSERT_THAT_EXPECTED(MaybeRVI20U64, Succeeded());
737   const auto &Exts = (*MaybeRVI20U64)->getExtensions();
738   EXPECT_EQ(Exts.size(), 4UL);
739   EXPECT_EQ(Exts.count("i"), 1U);
740   EXPECT_EQ(Exts.count("m"), 1U);
741   EXPECT_EQ(Exts.count("zba"), 1U);
742   EXPECT_EQ(Exts.count("zmmul"), 1U);
743 }
744 
745 TEST(ParseArchString,
746      RejectsProfilesWithAdditionalExtensionsGivenAlreadyInProfile) {
747   // This test was added to document the current behaviour. Discussion isn't
748   // believed to have taken place about if this is desirable or not.
749   EXPECT_EQ(
750       toString(
751           RISCVISAInfo::parseArchString("rva20u64_zicntr", true).takeError()),
752       "duplicated standard user-level extension 'zicntr'");
753 }
754 
755 TEST(ParseArchString,
756      RejectsExperimentalProfilesIfEnableExperimentalExtensionsNotSet) {
757   EXPECT_EQ(
758       toString(RISCVISAInfo::parseArchString("rvm23u32", false).takeError()),
759       "requires '-menable-experimental-extensions' for profile 'rvm23u32'");
760 }
761 
762 TEST(ToFeatures, IIsDroppedAndExperimentalExtensionsArePrefixed) {
763   auto MaybeISAInfo1 =
764       RISCVISAInfo::parseArchString("rv64im_zalasr", true, false);
765   ASSERT_THAT_EXPECTED(MaybeISAInfo1, Succeeded());
766   EXPECT_THAT((*MaybeISAInfo1)->toFeatures(),
767               ElementsAre("+m", "+zmmul", "+experimental-zalasr"));
768 
769   auto MaybeISAInfo2 = RISCVISAInfo::parseArchString(
770       "rv32e_zalasr_xventanacondops", true, false);
771   ASSERT_THAT_EXPECTED(MaybeISAInfo2, Succeeded());
772   EXPECT_THAT((*MaybeISAInfo2)->toFeatures(),
773               ElementsAre("+e", "+experimental-zalasr", "+xventanacondops"));
774 }
775 
776 TEST(ToFeatures, UnsupportedExtensionsAreDropped) {
777   auto MaybeISAInfo =
778       RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0_xmadeup1p0");
779   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
780   EXPECT_THAT((*MaybeISAInfo)->toFeatures(), ElementsAre("+m"));
781 }
782 
783 TEST(ToFeatures, UnsupportedExtensionsAreKeptIfIgnoreUnknownIsFalse) {
784   auto MaybeISAInfo =
785       RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0_xmadeup1p0");
786   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
787   EXPECT_THAT((*MaybeISAInfo)->toFeatures(false, false),
788               ElementsAre("+m", "+xmadeup"));
789 }
790 
791 TEST(ToFeatures, AddAllExtensionsAddsNegativeExtensions) {
792   auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0");
793   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
794 
795   auto Features = (*MaybeISAInfo)->toFeatures(true);
796   EXPECT_GT(Features.size(), 1UL);
797   EXPECT_EQ(Features.front(), "+m");
798   // Every feature after should be a negative feature
799   for (auto &NegativeExt : llvm::drop_begin(Features))
800     EXPECT_TRUE(NegativeExt.substr(0, 1) == "-");
801 }
802 
803 TEST(OrderedExtensionMap, ExtensionsAreCorrectlyOrdered) {
804   RISCVISAUtils::OrderedExtensionMap Exts;
805   for (auto ExtName : {"y", "l", "m", "c", "i", "xfoo", "xbar", "sfoo", "sbar",
806                        "zmfoo", "zzfoo", "zfinx", "zicsr"})
807     Exts[ExtName] = {1, 0};
808 
809   std::vector<std::string> ExtNames;
810   for (const auto &Ext : Exts)
811     ExtNames.push_back(Ext.first);
812 
813   // FIXME: 'l' and 'y' should be ordered after 'i', 'm', 'c'.
814   EXPECT_THAT(ExtNames,
815               ElementsAre("i", "m", "l", "c", "y", "zicsr", "zmfoo", "zfinx",
816                            "zzfoo", "sbar", "sfoo", "xbar", "xfoo"));
817 }
818 
819 TEST(ParseArchString, ZceImplication) {
820   auto MaybeRV32IZce = RISCVISAInfo::parseArchString("rv32izce", true);
821   ASSERT_THAT_EXPECTED(MaybeRV32IZce, Succeeded());
822   const auto &ExtsRV32IZce = (*MaybeRV32IZce)->getExtensions();
823   EXPECT_EQ(ExtsRV32IZce.size(), 7UL);
824   EXPECT_EQ(ExtsRV32IZce.count("i"), 1U);
825   EXPECT_EQ(ExtsRV32IZce.count("zicsr"), 1U);
826   EXPECT_EQ(ExtsRV32IZce.count("zca"), 1U);
827   EXPECT_EQ(ExtsRV32IZce.count("zcb"), 1U);
828   EXPECT_EQ(ExtsRV32IZce.count("zce"), 1U);
829   EXPECT_EQ(ExtsRV32IZce.count("zcmp"), 1U);
830   EXPECT_EQ(ExtsRV32IZce.count("zcmt"), 1U);
831 
832   auto MaybeRV32IFZce = RISCVISAInfo::parseArchString("rv32ifzce", true);
833   ASSERT_THAT_EXPECTED(MaybeRV32IFZce, Succeeded());
834   const auto &ExtsRV32IFZce = (*MaybeRV32IFZce)->getExtensions();
835   EXPECT_EQ(ExtsRV32IFZce.size(), 9UL);
836   EXPECT_EQ(ExtsRV32IFZce.count("i"), 1U);
837   EXPECT_EQ(ExtsRV32IFZce.count("zicsr"), 1U);
838   EXPECT_EQ(ExtsRV32IFZce.count("f"), 1U);
839   EXPECT_EQ(ExtsRV32IFZce.count("zca"), 1U);
840   EXPECT_EQ(ExtsRV32IFZce.count("zcb"), 1U);
841   EXPECT_EQ(ExtsRV32IFZce.count("zce"), 1U);
842   EXPECT_EQ(ExtsRV32IFZce.count("zcf"), 1U);
843   EXPECT_EQ(ExtsRV32IFZce.count("zcmp"), 1U);
844   EXPECT_EQ(ExtsRV32IFZce.count("zcmt"), 1U);
845 
846   auto MaybeRV32IDZce = RISCVISAInfo::parseArchString("rv32idzce", true);
847   ASSERT_THAT_EXPECTED(MaybeRV32IDZce, Succeeded());
848   const auto &ExtsRV32IDZce = (*MaybeRV32IDZce)->getExtensions();
849   EXPECT_EQ(ExtsRV32IDZce.size(), 10UL);
850   EXPECT_EQ(ExtsRV32IDZce.count("i"), 1U);
851   EXPECT_EQ(ExtsRV32IDZce.count("zicsr"), 1U);
852   EXPECT_EQ(ExtsRV32IDZce.count("f"), 1U);
853   EXPECT_EQ(ExtsRV32IDZce.count("d"), 1U);
854   EXPECT_EQ(ExtsRV32IDZce.count("zca"), 1U);
855   EXPECT_EQ(ExtsRV32IDZce.count("zcb"), 1U);
856   EXPECT_EQ(ExtsRV32IDZce.count("zce"), 1U);
857   EXPECT_EQ(ExtsRV32IDZce.count("zcf"), 1U);
858   EXPECT_EQ(ExtsRV32IDZce.count("zcmp"), 1U);
859   EXPECT_EQ(ExtsRV32IDZce.count("zcmt"), 1U);
860 
861   auto MaybeRV64IZce = RISCVISAInfo::parseArchString("rv64izce", true);
862   ASSERT_THAT_EXPECTED(MaybeRV64IZce, Succeeded());
863   const auto &ExtsRV64IZce = (*MaybeRV64IZce)->getExtensions();
864   EXPECT_EQ(ExtsRV64IZce.size(), 7UL);
865   EXPECT_EQ(ExtsRV64IZce.count("i"), 1U);
866   EXPECT_EQ(ExtsRV64IZce.count("zicsr"), 1U);
867   EXPECT_EQ(ExtsRV64IZce.count("zca"), 1U);
868   EXPECT_EQ(ExtsRV64IZce.count("zcb"), 1U);
869   EXPECT_EQ(ExtsRV64IZce.count("zce"), 1U);
870   EXPECT_EQ(ExtsRV64IZce.count("zcmp"), 1U);
871   EXPECT_EQ(ExtsRV64IZce.count("zcmt"), 1U);
872 
873   auto MaybeRV64IFZce = RISCVISAInfo::parseArchString("rv64ifzce", true);
874   ASSERT_THAT_EXPECTED(MaybeRV64IFZce, Succeeded());
875   const auto &ExtsRV64IFZce = (*MaybeRV64IFZce)->getExtensions();
876   EXPECT_EQ(ExtsRV64IFZce.size(), 8UL);
877   EXPECT_EQ(ExtsRV64IFZce.count("i"), 1U);
878   EXPECT_EQ(ExtsRV64IFZce.count("zicsr"), 1U);
879   EXPECT_EQ(ExtsRV64IFZce.count("f"), 1U);
880   EXPECT_EQ(ExtsRV64IFZce.count("zca"), 1U);
881   EXPECT_EQ(ExtsRV64IFZce.count("zcb"), 1U);
882   EXPECT_EQ(ExtsRV64IFZce.count("zce"), 1U);
883   EXPECT_EQ(ExtsRV64IFZce.count("zcmp"), 1U);
884   EXPECT_EQ(ExtsRV64IFZce.count("zcmt"), 1U);
885 
886   EXPECT_EQ(ExtsRV64IFZce.count("zca"), 1U);
887   EXPECT_EQ(ExtsRV64IFZce.count("zcb"), 1U);
888   EXPECT_EQ(ExtsRV64IFZce.count("zce"), 1U);
889   EXPECT_EQ(ExtsRV64IFZce.count("zcmp"), 1U);
890   EXPECT_EQ(ExtsRV64IFZce.count("zcmt"), 1U);
891 
892   auto MaybeRV64IDZce = RISCVISAInfo::parseArchString("rv64idzce", true);
893   ASSERT_THAT_EXPECTED(MaybeRV64IDZce, Succeeded());
894   const auto &ExtsRV64IDZce = (*MaybeRV64IDZce)->getExtensions();
895   EXPECT_EQ(ExtsRV64IDZce.size(), 9UL);
896   EXPECT_EQ(ExtsRV64IDZce.count("i"), 1U);
897   EXPECT_EQ(ExtsRV64IDZce.count("zicsr"), 1U);
898   EXPECT_EQ(ExtsRV64IDZce.count("f"), 1U);
899   EXPECT_EQ(ExtsRV64IDZce.count("d"), 1U);
900   EXPECT_EQ(ExtsRV64IDZce.count("zca"), 1U);
901   EXPECT_EQ(ExtsRV64IDZce.count("zcb"), 1U);
902   EXPECT_EQ(ExtsRV64IDZce.count("zce"), 1U);
903   EXPECT_EQ(ExtsRV64IDZce.count("zcmp"), 1U);
904   EXPECT_EQ(ExtsRV64IDZce.count("zcmt"), 1U);
905 }
906 
907 TEST(isSupportedExtensionWithVersion, AcceptsSingleExtensionWithVersion) {
908   EXPECT_TRUE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb1p0"));
909   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb"));
910   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo1p0"));
911   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo"));
912   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion(""));
913   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("c2p0zbb1p0"));
914 }
915 
916 TEST(getTargetFeatureForExtension, RetrieveTargetFeatureFromOneExt) {
917   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbb"), "zbb");
918   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso1p0"), "ztso");
919   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso"), "ztso");
920   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zihintntl1234p4321"),
921             "");
922   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zfoo"), "");
923   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension(""), "");
924   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbbzihintntl"), "");
925 }
926 
927 TEST(RiscvExtensionsHelp, CheckExtensions) {
928   // clang-format off
929   std::string ExpectedOutput =
930 R"(All available -march extensions for RISC-V
931 
932     Name                 Version   Description
933     i                    2.1       This is a long dummy description
934     e                    2.0
935     m                    2.0
936     a                    2.1
937     f                    2.2
938     d                    2.2
939     c                    2.0
940     b                    1.0
941     v                    1.0
942     h                    1.0
943     zic64b               1.0
944     zicbom               1.0
945     zicbop               1.0
946     zicboz               1.0
947     ziccamoa             1.0
948     ziccif               1.0
949     zicclsm              1.0
950     ziccrse              1.0
951     zicntr               2.0
952     zicond               1.0
953     zicsr                2.0
954     zifencei             2.0
955     zihintntl            1.0
956     zihintpause          2.0
957     zihpm                2.0
958     zimop                1.0
959     zmmul                1.0
960     za128rs              1.0
961     za64rs               1.0
962     zaamo                1.0
963     zabha                1.0
964     zacas                1.0
965     zalrsc               1.0
966     zama16b              1.0
967     zawrs                1.0
968     zfa                  1.0
969     zfbfmin              1.0
970     zfh                  1.0
971     zfhmin               1.0
972     zfinx                1.0
973     zdinx                1.0
974     zca                  1.0
975     zcb                  1.0
976     zcd                  1.0
977     zce                  1.0
978     zcf                  1.0
979     zcmop                1.0
980     zcmp                 1.0
981     zcmt                 1.0
982     zba                  1.0
983     zbb                  1.0
984     zbc                  1.0
985     zbkb                 1.0
986     zbkc                 1.0
987     zbkx                 1.0
988     zbs                  1.0
989     zk                   1.0
990     zkn                  1.0
991     zknd                 1.0
992     zkne                 1.0
993     zknh                 1.0
994     zkr                  1.0
995     zks                  1.0
996     zksed                1.0
997     zksh                 1.0
998     zkt                  1.0
999     ztso                 1.0
1000     zvbb                 1.0
1001     zvbc                 1.0
1002     zve32f               1.0
1003     zve32x               1.0
1004     zve64d               1.0
1005     zve64f               1.0
1006     zve64x               1.0
1007     zvfbfmin             1.0
1008     zvfbfwma             1.0
1009     zvfh                 1.0
1010     zvfhmin              1.0
1011     zvkb                 1.0
1012     zvkg                 1.0
1013     zvkn                 1.0
1014     zvknc                1.0
1015     zvkned               1.0
1016     zvkng                1.0
1017     zvknha               1.0
1018     zvknhb               1.0
1019     zvks                 1.0
1020     zvksc                1.0
1021     zvksed               1.0
1022     zvksg                1.0
1023     zvksh                1.0
1024     zvkt                 1.0
1025     zvl1024b             1.0
1026     zvl128b              1.0
1027     zvl16384b            1.0
1028     zvl2048b             1.0
1029     zvl256b              1.0
1030     zvl32768b            1.0
1031     zvl32b               1.0
1032     zvl4096b             1.0
1033     zvl512b              1.0
1034     zvl64b               1.0
1035     zvl65536b            1.0
1036     zvl8192b             1.0
1037     zhinx                1.0
1038     zhinxmin             1.0
1039     sha                  1.0
1040     shcounterenw         1.0
1041     shgatpa              1.0
1042     shtvala              1.0
1043     shvsatpa             1.0
1044     shvstvala            1.0
1045     shvstvecd            1.0
1046     smaia                1.0
1047     smcdeleg             1.0
1048     smcsrind             1.0
1049     smdbltrp             1.0
1050     smepmp               1.0
1051     smmpm                1.0
1052     smnpm                1.0
1053     smrnmi               1.0
1054     smstateen            1.0
1055     ssaia                1.0
1056     ssccfg               1.0
1057     ssccptr              1.0
1058     sscofpmf             1.0
1059     sscounterenw         1.0
1060     sscsrind             1.0
1061     ssdbltrp             1.0
1062     ssnpm                1.0
1063     sspm                 1.0
1064     ssqosid              1.0
1065     ssstateen            1.0
1066     ssstrict             1.0
1067     sstc                 1.0
1068     sstvala              1.0
1069     sstvecd              1.0
1070     ssu64xl              1.0
1071     supm                 1.0
1072     svade                1.0
1073     svadu                1.0
1074     svbare               1.0
1075     svinval              1.0
1076     svnapot              1.0
1077     svpbmt               1.0
1078     svvptc               1.0
1079     xcvalu               1.0
1080     xcvbi                1.0
1081     xcvbitmanip          1.0
1082     xcvelw               1.0
1083     xcvmac               1.0
1084     xcvmem               1.0
1085     xcvsimd              1.0
1086     xmipscmove           1.0
1087     xmipslsp             1.0
1088     xsfcease             1.0
1089     xsfvcp               1.0
1090     xsfvfnrclipxfqf      1.0
1091     xsfvfwmaccqqq        1.0
1092     xsfvqmaccdod         1.0
1093     xsfvqmaccqoq         1.0
1094     xsifivecdiscarddlone 1.0
1095     xsifivecflushdlone   1.0
1096     xtheadba             1.0
1097     xtheadbb             1.0
1098     xtheadbs             1.0
1099     xtheadcmo            1.0
1100     xtheadcondmov        1.0
1101     xtheadfmemidx        1.0
1102     xtheadmac            1.0
1103     xtheadmemidx         1.0
1104     xtheadmempair        1.0
1105     xtheadsync           1.0
1106     xtheadvdot           1.0
1107     xventanacondops      1.0
1108     xwchc                2.2
1109 
1110 Experimental extensions
1111     zicfilp              1.0       This is a long dummy description
1112     zicfiss              1.0
1113     zalasr               0.1
1114     zvbc32e              0.7
1115     zvkgs                0.7
1116     sdext                1.0
1117     sdtrig               1.0
1118     smctr                1.0
1119     ssctr                1.0
1120     svukte               0.3
1121     xqcia                0.2
1122     xqciac               0.3
1123     xqcicli              0.2
1124     xqcicm               0.2
1125     xqcics               0.2
1126     xqcicsr              0.2
1127     xqciint              0.2
1128     xqcilo               0.2
1129     xqcilsm              0.2
1130     xqcisls              0.2
1131 
1132 Supported Profiles
1133     rva20s64
1134     rva20u64
1135     rva22s64
1136     rva22u64
1137     rva23s64
1138     rva23u64
1139     rvb23s64
1140     rvb23u64
1141     rvi20u32
1142     rvi20u64
1143 
1144 Experimental Profiles
1145     rvm23u32
1146 
1147 Use -march to specify the target's extension.
1148 For example, clang -march=rv32i_v1p0)";
1149   // clang-format on
1150 
1151   StringMap<StringRef> DummyMap;
1152   DummyMap["i"] = "This is a long dummy description";
1153   DummyMap["experimental-zicfilp"] = "This is a long dummy description";
1154 
1155   outs().flush();
1156   testing::internal::CaptureStdout();
1157   RISCVISAInfo::printSupportedExtensions(DummyMap);
1158   outs().flush();
1159 
1160   std::string CapturedOutput = testing::internal::GetCapturedStdout();
1161   EXPECT_TRUE([](std::string &Captured, std::string &Expected) {
1162                 return Captured.find(Expected) != std::string::npos;
1163               }(CapturedOutput, ExpectedOutput));
1164 }
1165 
1166 TEST(TargetParserTest, RISCVPrintEnabledExtensions) {
1167   // clang-format off
1168   std::string ExpectedOutput =
1169 R"(Extensions enabled for the given RISC-V target
1170 
1171     Name                 Version   Description
1172     i                    2.1       'I' (Base Integer Instruction Set)
1173 
1174 Experimental extensions
1175     zicfilp              1.0       'Zicfilp' (Landing pad)
1176 
1177 ISA String: rv64i2p1_zicfilp1p0_zicsr2p0
1178 )";
1179   // clang-format on
1180 
1181   StringMap<StringRef> DescMap;
1182   DescMap["i"] = "'I' (Base Integer Instruction Set)";
1183   DescMap["experimental-zicfilp"] = "'Zicfilp' (Landing pad)";
1184   std::set<StringRef> EnabledExtensions = {"i", "experimental-zicfilp"};
1185 
1186   outs().flush();
1187   testing::internal::CaptureStdout();
1188   RISCVISAInfo::printEnabledExtensions(/*IsRV64=*/true, EnabledExtensions,
1189                                        DescMap);
1190   outs().flush();
1191   std::string CapturedOutput = testing::internal::GetCapturedStdout();
1192 
1193   EXPECT_EQ(CapturedOutput, ExpectedOutput);
1194 }
1195