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
14using ::testing::ElementsAre;
15
16using namespace llvm;
17
18bool operator==(const RISCVISAUtils::ExtensionVersion &A,
19 const RISCVISAUtils::ExtensionVersion &B) {
20 return A.Major == B.Major && A.Minor == B.Minor;
21}
22
23TEST(ParseNormalizedArchString, RejectsUpperCase) {
24 for (StringRef Input : {"RV32", "rV64", "rv32i2P0", "rv64i2p0_A2p0"}) {
25 EXPECT_EQ(
26 toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
27 "string must be lowercase");
28 }
29}
30
31TEST(ParseNormalizedArchString, RejectsInvalidBaseISA) {
32 for (StringRef Input : {"rv32", "rv64", "rv32j", "rv65i"}) {
33 EXPECT_EQ(
34 toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
35 "arch string must begin with valid base ISA");
36 }
37}
38
39TEST(ParseNormalizedArchString, RejectsMalformedInputs) {
40 for (StringRef Input : {"rv64i2p0_", "rv32i2p0__a2p0", "rv32e2.0", "rv64e2p",
41 "rv32i", "rv64ip1"}) {
42 EXPECT_EQ(
43 toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
44 "extension lacks version in expected format");
45 }
46}
47
48TEST(ParseNormalizedArchString, AcceptsValidBaseISAsAndSetsXLen) {
49 auto MaybeRV32I = RISCVISAInfo::parseNormalizedArchString(Arch: "rv32i2p0");
50 ASSERT_THAT_EXPECTED(MaybeRV32I, Succeeded());
51 RISCVISAInfo &InfoRV32I = **MaybeRV32I;
52 EXPECT_EQ(InfoRV32I.getExtensions().size(), 1UL);
53 EXPECT_TRUE(InfoRV32I.getExtensions().at("i") ==
54 (RISCVISAUtils::ExtensionVersion{2, 0}));
55 EXPECT_EQ(InfoRV32I.getXLen(), 32U);
56
57 auto MaybeRV32E = RISCVISAInfo::parseNormalizedArchString(Arch: "rv32e2p0");
58 ASSERT_THAT_EXPECTED(MaybeRV32E, Succeeded());
59 RISCVISAInfo &InfoRV32E = **MaybeRV32E;
60 EXPECT_EQ(InfoRV32E.getExtensions().size(), 1UL);
61 EXPECT_TRUE(InfoRV32E.getExtensions().at("e") ==
62 (RISCVISAUtils::ExtensionVersion{2, 0}));
63 EXPECT_EQ(InfoRV32E.getXLen(), 32U);
64
65 auto MaybeRV64I = RISCVISAInfo::parseNormalizedArchString(Arch: "rv64i2p0");
66 ASSERT_THAT_EXPECTED(MaybeRV64I, Succeeded());
67 RISCVISAInfo &InfoRV64I = **MaybeRV64I;
68 EXPECT_EQ(InfoRV64I.getExtensions().size(), 1UL);
69 EXPECT_TRUE(InfoRV64I.getExtensions().at("i") ==
70 (RISCVISAUtils::ExtensionVersion{2, 0}));
71 EXPECT_EQ(InfoRV64I.getXLen(), 64U);
72
73 auto MaybeRV64E = RISCVISAInfo::parseNormalizedArchString(Arch: "rv64e2p0");
74 ASSERT_THAT_EXPECTED(MaybeRV64E, Succeeded());
75 RISCVISAInfo &InfoRV64E = **MaybeRV64E;
76 EXPECT_EQ(InfoRV64E.getExtensions().size(), 1UL);
77 EXPECT_TRUE(InfoRV64E.getExtensions().at("e") ==
78 (RISCVISAUtils::ExtensionVersion{2, 0}));
79 EXPECT_EQ(InfoRV64E.getXLen(), 64U);
80}
81
82TEST(ParseNormalizedArchString, AcceptsArbitraryExtensionsAndVersions) {
83 auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString(
84 Arch: "rv64i5p1_m3p2_zmadeup11p12_sfoo2p0_xbar3p0");
85 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
86 RISCVISAInfo &Info = **MaybeISAInfo;
87 EXPECT_EQ(Info.getExtensions().size(), 5UL);
88 EXPECT_TRUE(Info.getExtensions().at("i") ==
89 (RISCVISAUtils::ExtensionVersion{5, 1}));
90 EXPECT_TRUE(Info.getExtensions().at("m") ==
91 (RISCVISAUtils::ExtensionVersion{3, 2}));
92 EXPECT_TRUE(Info.getExtensions().at("zmadeup") ==
93 (RISCVISAUtils::ExtensionVersion{11, 12}));
94 EXPECT_TRUE(Info.getExtensions().at("sfoo") ==
95 (RISCVISAUtils::ExtensionVersion{2, 0}));
96 EXPECT_TRUE(Info.getExtensions().at("xbar") ==
97 (RISCVISAUtils::ExtensionVersion{3, 0}));
98}
99
100TEST(ParseNormalizedArchString, UpdatesFLenMinVLenMaxELen) {
101 auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString(
102 Arch: "rv64i2p0_d2p0_zvl64b1p0_zve64d1p0");
103 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
104 RISCVISAInfo &Info = **MaybeISAInfo;
105 EXPECT_EQ(Info.getXLen(), 64U);
106 EXPECT_EQ(Info.getFLen(), 64U);
107 EXPECT_EQ(Info.getMinVLen(), 64U);
108 EXPECT_EQ(Info.getMaxELen(), 64U);
109}
110
111TEST(ParseArchString, RejectsUpperCase) {
112 for (StringRef Input : {"RV32", "rV64", "rv32i2P0", "rv64i2p0_A2p0"}) {
113 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
114 "string must be lowercase");
115 }
116}
117
118TEST(ParseArchString, RejectsInvalidBaseISA) {
119 for (StringRef Input : {"rv32", "rv64", "rv65i"}) {
120 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
121 "string must begin with rv32{i,e,g} or rv64{i,e,g}");
122 }
123 for (StringRef Input : {"rv32j", "rv64k", "rv32_i"}) {
124 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
125 "first letter should be 'e', 'i' or 'g'");
126 }
127}
128
129TEST(ParseArchString, RejectsUnsupportedBaseISA) {
130 for (StringRef Input : {"rv128i", "rv128g"}) {
131 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
132 "string must begin with rv32{i,e,g} or rv64{i,e,g}");
133 }
134}
135
136TEST(ParseArchString, AcceptsSupportedBaseISAsAndSetsXLenAndFLen) {
137 auto MaybeRV32I = RISCVISAInfo::parseArchString(Arch: "rv32i", EnableExperimentalExtension: true);
138 ASSERT_THAT_EXPECTED(MaybeRV32I, Succeeded());
139 RISCVISAInfo &InfoRV32I = **MaybeRV32I;
140 RISCVISAInfo::OrderedExtensionMap ExtsRV32I = InfoRV32I.getExtensions();
141 EXPECT_EQ(ExtsRV32I.size(), 1UL);
142 EXPECT_TRUE(ExtsRV32I.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
143 EXPECT_EQ(InfoRV32I.getXLen(), 32U);
144 EXPECT_EQ(InfoRV32I.getFLen(), 0U);
145
146 auto MaybeRV32E = RISCVISAInfo::parseArchString(Arch: "rv32e", EnableExperimentalExtension: true);
147 ASSERT_THAT_EXPECTED(MaybeRV32E, Succeeded());
148 RISCVISAInfo &InfoRV32E = **MaybeRV32E;
149 RISCVISAInfo::OrderedExtensionMap ExtsRV32E = InfoRV32E.getExtensions();
150 EXPECT_EQ(ExtsRV32E.size(), 1UL);
151 EXPECT_TRUE(ExtsRV32E.at("e") == (RISCVISAUtils::ExtensionVersion{2, 0}));
152 EXPECT_EQ(InfoRV32E.getXLen(), 32U);
153 EXPECT_EQ(InfoRV32E.getFLen(), 0U);
154
155 auto MaybeRV32G = RISCVISAInfo::parseArchString(Arch: "rv32g", EnableExperimentalExtension: true);
156 ASSERT_THAT_EXPECTED(MaybeRV32G, Succeeded());
157 RISCVISAInfo &InfoRV32G = **MaybeRV32G;
158 RISCVISAInfo::OrderedExtensionMap ExtsRV32G = InfoRV32G.getExtensions();
159 EXPECT_EQ(ExtsRV32G.size(), 7UL);
160 EXPECT_TRUE(ExtsRV32G.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
161 EXPECT_TRUE(ExtsRV32G.at("m") == (RISCVISAUtils::ExtensionVersion{2, 0}));
162 EXPECT_TRUE(ExtsRV32G.at("a") == (RISCVISAUtils::ExtensionVersion{2, 1}));
163 EXPECT_TRUE(ExtsRV32G.at("f") == (RISCVISAUtils::ExtensionVersion{2, 2}));
164 EXPECT_TRUE(ExtsRV32G.at("d") == (RISCVISAUtils::ExtensionVersion{2, 2}));
165 EXPECT_TRUE(ExtsRV32G.at("zicsr") == (RISCVISAUtils::ExtensionVersion{2, 0}));
166 EXPECT_TRUE(ExtsRV32G.at("zifencei") ==
167 (RISCVISAUtils::ExtensionVersion{2, 0}));
168 EXPECT_EQ(InfoRV32G.getXLen(), 32U);
169 EXPECT_EQ(InfoRV32G.getFLen(), 64U);
170
171 auto MaybeRV64I = RISCVISAInfo::parseArchString(Arch: "rv64i", EnableExperimentalExtension: true);
172 ASSERT_THAT_EXPECTED(MaybeRV64I, Succeeded());
173 RISCVISAInfo &InfoRV64I = **MaybeRV64I;
174 RISCVISAInfo::OrderedExtensionMap ExtsRV64I = InfoRV64I.getExtensions();
175 EXPECT_EQ(ExtsRV64I.size(), 1UL);
176 EXPECT_TRUE(ExtsRV64I.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
177 EXPECT_EQ(InfoRV64I.getXLen(), 64U);
178 EXPECT_EQ(InfoRV64I.getFLen(), 0U);
179
180 auto MaybeRV64E = RISCVISAInfo::parseArchString(Arch: "rv64e", EnableExperimentalExtension: true);
181 ASSERT_THAT_EXPECTED(MaybeRV64E, Succeeded());
182 RISCVISAInfo &InfoRV64E = **MaybeRV64E;
183 RISCVISAInfo::OrderedExtensionMap ExtsRV64E = InfoRV64E.getExtensions();
184 EXPECT_EQ(ExtsRV64E.size(), 1UL);
185 EXPECT_TRUE(ExtsRV64E.at("e") == (RISCVISAUtils::ExtensionVersion{2, 0}));
186 EXPECT_EQ(InfoRV64E.getXLen(), 64U);
187 EXPECT_EQ(InfoRV64E.getFLen(), 0U);
188
189 auto MaybeRV64G = RISCVISAInfo::parseArchString(Arch: "rv64g", EnableExperimentalExtension: true);
190 ASSERT_THAT_EXPECTED(MaybeRV64G, Succeeded());
191 RISCVISAInfo &InfoRV64G = **MaybeRV64G;
192 RISCVISAInfo::OrderedExtensionMap ExtsRV64G = InfoRV64G.getExtensions();
193 EXPECT_EQ(ExtsRV64G.size(), 7UL);
194 EXPECT_TRUE(ExtsRV64G.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
195 EXPECT_TRUE(ExtsRV64G.at("m") == (RISCVISAUtils::ExtensionVersion{2, 0}));
196 EXPECT_TRUE(ExtsRV64G.at("a") == (RISCVISAUtils::ExtensionVersion{2, 1}));
197 EXPECT_TRUE(ExtsRV64G.at("f") == (RISCVISAUtils::ExtensionVersion{2, 2}));
198 EXPECT_TRUE(ExtsRV64G.at("d") == (RISCVISAUtils::ExtensionVersion{2, 2}));
199 EXPECT_TRUE(ExtsRV64G.at("zicsr") == (RISCVISAUtils::ExtensionVersion{2, 0}));
200 EXPECT_TRUE(ExtsRV64G.at("zifencei") ==
201 (RISCVISAUtils::ExtensionVersion{2, 0}));
202 EXPECT_EQ(InfoRV64G.getXLen(), 64U);
203 EXPECT_EQ(InfoRV64G.getFLen(), 64U);
204}
205
206TEST(ParseArchString, RejectsUnrecognizedExtensionNamesByDefault) {
207 EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv64ib", true).takeError()),
208 "unsupported standard user-level extension 'b'");
209 EXPECT_EQ(
210 toString(
211 RISCVISAInfo::parseArchString("rv32i_zmadeup", true).takeError()),
212 "unsupported standard user-level extension 'zmadeup'");
213 EXPECT_EQ(
214 toString(
215 RISCVISAInfo::parseArchString("rv64g_smadeup", true).takeError()),
216 "unsupported standard supervisor-level extension 'smadeup'");
217 EXPECT_EQ(
218 toString(
219 RISCVISAInfo::parseArchString("rv64g_xmadeup", true).takeError()),
220 "unsupported non-standard user-level extension 'xmadeup'");
221 EXPECT_EQ(
222 toString(RISCVISAInfo::parseArchString("rv64ib1p0", true).takeError()),
223 "unsupported standard user-level extension 'b'");
224 EXPECT_EQ(
225 toString(
226 RISCVISAInfo::parseArchString("rv32i_zmadeup1p0", true).takeError()),
227 "unsupported standard user-level extension 'zmadeup'");
228 EXPECT_EQ(
229 toString(
230 RISCVISAInfo::parseArchString("rv64g_smadeup1p0", true).takeError()),
231 "unsupported standard supervisor-level extension 'smadeup'");
232 EXPECT_EQ(
233 toString(
234 RISCVISAInfo::parseArchString("rv64g_xmadeup1p0", true).takeError()),
235 "unsupported non-standard user-level extension 'xmadeup'");
236}
237
238TEST(ParseArchString, IgnoresUnrecognizedExtensionNamesWithIgnoreUnknown) {
239 for (StringRef Input : {"rv32ib", "rv32i_zmadeup",
240 "rv64i_smadeup", "rv64i_xmadeup"}) {
241 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true, ExperimentalExtensionVersionCheck: false, IgnoreUnknown: true);
242 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
243 RISCVISAInfo &Info = **MaybeISAInfo;
244 RISCVISAInfo::OrderedExtensionMap Exts = Info.getExtensions();
245 EXPECT_EQ(Exts.size(), 1UL);
246 EXPECT_TRUE(Exts.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
247 }
248
249 // Checks that supported extensions aren't incorrectly ignored when a
250 // version is present (an early version of the patch had this mistake).
251 auto MaybeISAInfo =
252 RISCVISAInfo::parseArchString(Arch: "rv32i_zbc1p0_xmadeup", EnableExperimentalExtension: true, ExperimentalExtensionVersionCheck: false, IgnoreUnknown: true);
253 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
254 RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions();
255 EXPECT_TRUE(Exts.at("zbc") == (RISCVISAUtils::ExtensionVersion{1, 0}));
256}
257
258TEST(ParseArchString, AcceptsVersionInLongOrShortForm) {
259 for (StringRef Input : {"rv64i2p1"}) {
260 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true);
261 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
262 RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions();
263 EXPECT_TRUE(Exts.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
264 }
265 for (StringRef Input : {"rv32i_zfinx1", "rv32i_zfinx1p0"}) {
266 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true);
267 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
268 RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions();
269 EXPECT_TRUE(Exts.at("zfinx") == (RISCVISAUtils::ExtensionVersion{1, 0}));
270 }
271}
272
273TEST(ParseArchString, RejectsUnrecognizedExtensionVersionsByDefault) {
274 EXPECT_EQ(
275 toString(RISCVISAInfo::parseArchString("rv64i2p", true).takeError()),
276 "minor version number missing after 'p' for extension 'i'");
277 EXPECT_EQ(
278 toString(RISCVISAInfo::parseArchString("rv64i1p0", true).takeError()),
279 "unsupported version number 1.0 for extension 'i'");
280 EXPECT_EQ(
281 toString(RISCVISAInfo::parseArchString("rv64i9p9", true).takeError()),
282 "unsupported version number 9.9 for extension 'i'");
283 EXPECT_EQ(
284 toString(RISCVISAInfo::parseArchString("rv32im0p1", true).takeError()),
285 "unsupported version number 0.1 for extension 'm'");
286 EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv32izifencei10p10", true)
287 .takeError()),
288 "unsupported version number 10.10 for extension 'zifencei'");
289}
290
291TEST(ParseArchString,
292 UsesDefaultVersionForUnrecognisedBaseISAVersionWithIgnoreUnknown) {
293 for (StringRef Input : {"rv32i0p1", "rv32i99p99", "rv64i0p1", "rv64i99p99"}) {
294 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true, ExperimentalExtensionVersionCheck: false, IgnoreUnknown: true);
295 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
296 RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions();
297 EXPECT_EQ(Exts.size(), 1UL);
298 EXPECT_TRUE(Exts.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
299 }
300 for (StringRef Input : {"rv32e0p1", "rv32e99p99", "rv64e0p1", "rv64e99p99"}) {
301 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true, ExperimentalExtensionVersionCheck: false, IgnoreUnknown: true);
302 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
303 RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions();
304 EXPECT_EQ(Exts.size(), 1UL);
305 EXPECT_TRUE(Exts.at("e") == (RISCVISAUtils::ExtensionVersion{2, 0}));
306 }
307}
308
309TEST(ParseArchString,
310 IgnoresExtensionsWithUnrecognizedVersionsWithIgnoreUnknown) {
311 for (StringRef Input : {"rv32im1p1", "rv64i_svnapot10p9", "rv32i_zicsr0p5"}) {
312 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true, ExperimentalExtensionVersionCheck: false, IgnoreUnknown: true);
313 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
314 RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions();
315 EXPECT_EQ(Exts.size(), 1UL);
316 EXPECT_TRUE(Exts.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
317 }
318}
319
320TEST(ParseArchString, AcceptsUnderscoreSplittingExtensions) {
321 for (StringRef Input : {"rv32imafdczifencei", "rv32i_m_a_f_d_c_zifencei"}) {
322 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true);
323 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
324 RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions();
325 EXPECT_EQ(Exts.size(), 8UL);
326 EXPECT_EQ(Exts.count("i"), 1U);
327 EXPECT_EQ(Exts.count("m"), 1U);
328 EXPECT_EQ(Exts.count("a"), 1U);
329 EXPECT_EQ(Exts.count("f"), 1U);
330 EXPECT_EQ(Exts.count("d"), 1U);
331 EXPECT_EQ(Exts.count("c"), 1U);
332 EXPECT_EQ(Exts.count("zicsr"), 1U);
333 EXPECT_EQ(Exts.count("zifencei"), 1U);
334 }
335}
336
337TEST(ParseArchString, AcceptsRelaxSingleLetterExtensions) {
338 for (StringRef Input :
339 {"rv32imfad", "rv32im_fa_d", "rv32im2p0fad", "rv32i2p1m2p0fad"}) {
340 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true);
341 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
342 RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions();
343 EXPECT_EQ(Exts.size(), 6UL);
344 EXPECT_EQ(Exts.count("i"), 1U);
345 EXPECT_EQ(Exts.count("m"), 1U);
346 EXPECT_EQ(Exts.count("f"), 1U);
347 EXPECT_EQ(Exts.count("a"), 1U);
348 EXPECT_EQ(Exts.count("d"), 1U);
349 EXPECT_EQ(Exts.count("zicsr"), 1U);
350 }
351}
352
353TEST(ParseArchString, AcceptsRelaxMixedLetterExtensions) {
354 for (StringRef Input :
355 {"rv32i_zihintntl_m_a_f_d_svinval", "rv32izihintntl_mafdsvinval",
356 "rv32i_zihintntl_mafd_svinval"}) {
357 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true);
358 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
359 RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions();
360 EXPECT_EQ(Exts.size(), 8UL);
361 EXPECT_EQ(Exts.count("i"), 1U);
362 EXPECT_EQ(Exts.count("m"), 1U);
363 EXPECT_EQ(Exts.count("a"), 1U);
364 EXPECT_EQ(Exts.count("f"), 1U);
365 EXPECT_EQ(Exts.count("d"), 1U);
366 EXPECT_EQ(Exts.count("zihintntl"), 1U);
367 EXPECT_EQ(Exts.count("svinval"), 1U);
368 EXPECT_EQ(Exts.count("zicsr"), 1U);
369 }
370}
371
372TEST(ParseArchString, AcceptsAmbiguousFromRelaxExtensions) {
373 for (StringRef Input : {"rv32i_zba_m", "rv32izba_m", "rv32izba1p0_m2p0"}) {
374 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true);
375 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
376 RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions();
377 EXPECT_EQ(Exts.size(), 3UL);
378 EXPECT_EQ(Exts.count("i"), 1U);
379 EXPECT_EQ(Exts.count("zba"), 1U);
380 EXPECT_EQ(Exts.count("m"), 1U);
381 }
382 for (StringRef Input :
383 {"rv32ia_zba_m", "rv32iazba_m", "rv32ia2p1zba1p0_m2p0"}) {
384 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: Input, EnableExperimentalExtension: true);
385 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
386 RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions();
387 EXPECT_EQ(Exts.size(), 4UL);
388 EXPECT_EQ(Exts.count("i"), 1U);
389 EXPECT_EQ(Exts.count("zba"), 1U);
390 EXPECT_EQ(Exts.count("m"), 1U);
391 EXPECT_EQ(Exts.count("a"), 1U);
392 }
393}
394
395TEST(ParseArchString, RejectsRelaxExtensionsNotStartWithEorIorG) {
396 EXPECT_EQ(
397 toString(RISCVISAInfo::parseArchString("rv32zba_im", true).takeError()),
398 "first letter should be 'e', 'i' or 'g'");
399}
400
401TEST(ParseArchString,
402 RejectsMultiLetterExtensionFollowBySingleLetterExtensions) {
403 for (StringRef Input : {"rv32izbam", "rv32i_zbam"})
404 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
405 "unsupported standard user-level extension 'zbam'");
406 EXPECT_EQ(
407 toString(RISCVISAInfo::parseArchString("rv32izbai_m", true).takeError()),
408 "unsupported standard user-level extension 'zbai'");
409 EXPECT_EQ(
410 toString(RISCVISAInfo::parseArchString("rv32izbaim", true).takeError()),
411 "unsupported standard user-level extension 'zbaim'");
412 EXPECT_EQ(
413 toString(
414 RISCVISAInfo::parseArchString("rv32i_zba1p0m", true).takeError()),
415 "unsupported standard user-level extension 'zba1p0m'");
416}
417
418TEST(ParseArchString, RejectsDoubleOrTrailingUnderscore) {
419 EXPECT_EQ(
420 toString(RISCVISAInfo::parseArchString("rv64i__m", true).takeError()),
421 "extension name missing after separator '_'");
422
423 for (StringRef Input :
424 {"rv32ezicsr__zifencei", "rv32i_", "rv32izicsr_", "rv64im_"}) {
425 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
426 "extension name missing after separator '_'");
427 }
428}
429
430TEST(ParseArchString, RejectsDuplicateExtensionNames) {
431 EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv64ii", true).takeError()),
432 "invalid standard user-level extension 'i'");
433 EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv32ee", true).takeError()),
434 "invalid standard user-level extension 'e'");
435 EXPECT_EQ(
436 toString(RISCVISAInfo::parseArchString("rv64imm", true).takeError()),
437 "duplicated standard user-level extension 'm'");
438 EXPECT_EQ(
439 toString(
440 RISCVISAInfo::parseArchString("rv32i_zicsr_zicsr", true).takeError()),
441 "duplicated standard user-level extension 'zicsr'");
442}
443
444TEST(ParseArchString,
445 RejectsExperimentalExtensionsIfNotEnableExperimentalExtension) {
446 EXPECT_EQ(
447 toString(RISCVISAInfo::parseArchString("rv64iztso", false).takeError()),
448 "requires '-menable-experimental-extensions' for experimental extension "
449 "'ztso'");
450}
451
452TEST(ParseArchString,
453 AcceptsExperimentalExtensionsIfEnableExperimentalExtension) {
454 // Note: If ztso becomes none-experimental, this test will need
455 // updating (and unfortunately, it will still pass). The failure of
456 // RejectsExperimentalExtensionsIfNotEnableExperimentalExtension will
457 // hopefully serve as a reminder to update.
458 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Arch: "rv64iztso", EnableExperimentalExtension: true, ExperimentalExtensionVersionCheck: false);
459 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
460 RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions();
461 EXPECT_EQ(Exts.size(), 2UL);
462 EXPECT_EQ(Exts.count("ztso"), 1U);
463 auto MaybeISAInfo2 = RISCVISAInfo::parseArchString(Arch: "rv64iztso0p1", EnableExperimentalExtension: true);
464 ASSERT_THAT_EXPECTED(MaybeISAInfo2, Succeeded());
465 RISCVISAInfo::OrderedExtensionMap Exts2 = (*MaybeISAInfo2)->getExtensions();
466 EXPECT_EQ(Exts2.size(), 2UL);
467 EXPECT_EQ(Exts2.count("ztso"), 1U);
468}
469
470TEST(ParseArchString,
471 RequiresExplicitVersionNumberForExperimentalExtensionByDefault) {
472 EXPECT_EQ(
473 toString(RISCVISAInfo::parseArchString("rv64iztso", true).takeError()),
474 "experimental extension requires explicit version number `ztso`");
475}
476
477TEST(ParseArchString,
478 AcceptsUnrecognizedVersionIfNotExperimentalExtensionVersionCheck) {
479 auto MaybeISAInfo =
480 RISCVISAInfo::parseArchString(Arch: "rv64iztso9p9", EnableExperimentalExtension: true, ExperimentalExtensionVersionCheck: false);
481 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
482 RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions();
483 EXPECT_EQ(Exts.size(), 2UL);
484 EXPECT_TRUE(Exts.at("ztso") == (RISCVISAUtils::ExtensionVersion{9, 9}));
485}
486
487TEST(ParseArchString, RejectsUnrecognizedVersionForExperimentalExtension) {
488 EXPECT_EQ(
489 toString(RISCVISAInfo::parseArchString("rv64iztso9p9", true).takeError()),
490 "unsupported version number 9.9 for experimental extension 'ztso' "
491 "(this compiler supports 0.1)");
492}
493
494TEST(ParseArchString, RejectsExtensionVersionForG) {
495 for (StringRef Input : {"rv32g1c", "rv64g2p0"}) {
496 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
497 "version not supported for 'g'");
498 }
499}
500
501TEST(ParseArchString, AddsImpliedExtensions) {
502 // Does not attempt to exhaustively test all implications.
503 auto MaybeRV64ID = RISCVISAInfo::parseArchString(Arch: "rv64id", EnableExperimentalExtension: true);
504 ASSERT_THAT_EXPECTED(MaybeRV64ID, Succeeded());
505 RISCVISAInfo::OrderedExtensionMap ExtsRV64ID =
506 (*MaybeRV64ID)->getExtensions();
507 EXPECT_EQ(ExtsRV64ID.size(), 4UL);
508 EXPECT_EQ(ExtsRV64ID.count("i"), 1U);
509 EXPECT_EQ(ExtsRV64ID.count("f"), 1U);
510 EXPECT_EQ(ExtsRV64ID.count("d"), 1U);
511 EXPECT_EQ(ExtsRV64ID.count("zicsr"), 1U);
512
513 auto MaybeRV32IZKN = RISCVISAInfo::parseArchString(Arch: "rv64izkn", EnableExperimentalExtension: true);
514 ASSERT_THAT_EXPECTED(MaybeRV32IZKN, Succeeded());
515 RISCVISAInfo::OrderedExtensionMap ExtsRV32IZKN =
516 (*MaybeRV32IZKN)->getExtensions();
517 EXPECT_EQ(ExtsRV32IZKN.size(), 8UL);
518 EXPECT_EQ(ExtsRV32IZKN.count("i"), 1U);
519 EXPECT_EQ(ExtsRV32IZKN.count("zbkb"), 1U);
520 EXPECT_EQ(ExtsRV32IZKN.count("zbkc"), 1U);
521 EXPECT_EQ(ExtsRV32IZKN.count("zbkx"), 1U);
522 EXPECT_EQ(ExtsRV32IZKN.count("zkne"), 1U);
523 EXPECT_EQ(ExtsRV32IZKN.count("zknd"), 1U);
524 EXPECT_EQ(ExtsRV32IZKN.count("zknh"), 1U);
525 EXPECT_EQ(ExtsRV32IZKN.count("zkn"), 1U);
526}
527
528TEST(ParseArchString, RejectsConflictingExtensions) {
529 for (StringRef Input : {"rv32ifzfinx", "rv64gzdinx"}) {
530 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
531 "'f' and 'zfinx' extensions are incompatible");
532 }
533
534 for (StringRef Input : {"rv32idc_zcmp1p0", "rv64idc_zcmp1p0"}) {
535 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
536 "'zcmp' extension is incompatible with 'c' extension when 'd' "
537 "extension is enabled");
538 }
539
540 for (StringRef Input : {"rv32id_zcd1p0_zcmp1p0", "rv64id_zcd1p0_zcmp1p0"}) {
541 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
542 "'zcmp' extension is incompatible with 'zcd' extension when 'd' "
543 "extension is enabled");
544 }
545
546 for (StringRef Input : {"rv32idc_zcmt1p0", "rv64idc_zcmt1p0"}) {
547 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
548 "'zcmt' extension is incompatible with 'c' extension when 'd' "
549 "extension is enabled");
550 }
551
552 for (StringRef Input : {"rv32id_zcd1p0_zcmt1p0", "rv64id_zcd1p0_zcmt1p0"}) {
553 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
554 "'zcmt' extension is incompatible with 'zcd' extension when 'd' "
555 "extension is enabled");
556 }
557
558 for (StringRef Input : {"rv64if_zcf"}) {
559 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
560 "'zcf' is only supported for 'rv32'");
561 }
562}
563
564TEST(ToFeatures, IIsDroppedAndExperimentalExtensionsArePrefixed) {
565 auto MaybeISAInfo1 =
566 RISCVISAInfo::parseArchString(Arch: "rv64im_ztso", EnableExperimentalExtension: true, ExperimentalExtensionVersionCheck: false);
567 ASSERT_THAT_EXPECTED(MaybeISAInfo1, Succeeded());
568 EXPECT_THAT((*MaybeISAInfo1)->toFeatures(),
569 ElementsAre("+m", "+experimental-ztso"));
570
571 auto MaybeISAInfo2 =
572 RISCVISAInfo::parseArchString(Arch: "rv32e_ztso_xventanacondops", EnableExperimentalExtension: true, ExperimentalExtensionVersionCheck: false);
573 ASSERT_THAT_EXPECTED(MaybeISAInfo2, Succeeded());
574 EXPECT_THAT((*MaybeISAInfo2)->toFeatures(),
575 ElementsAre("+e", "+experimental-ztso", "+xventanacondops"));
576}
577
578TEST(ToFeatures, UnsupportedExtensionsAreDropped) {
579 auto MaybeISAInfo =
580 RISCVISAInfo::parseNormalizedArchString(Arch: "rv64i2p0_m2p0_xmadeup1p0");
581 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
582 EXPECT_THAT((*MaybeISAInfo)->toFeatures(), ElementsAre("+m"));
583}
584
585TEST(ToFeatures, UnsupportedExtensionsAreKeptIfIgnoreUnknownIsFalse) {
586 auto MaybeISAInfo =
587 RISCVISAInfo::parseNormalizedArchString(Arch: "rv64i2p0_m2p0_xmadeup1p0");
588 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
589 EXPECT_THAT((*MaybeISAInfo)->toFeatures(false, false),
590 ElementsAre("+m", "+xmadeup"));
591}
592
593TEST(ToFeatures, AddAllExtensionsAddsNegativeExtensions) {
594 auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString(Arch: "rv64i2p0_m2p0");
595 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
596
597 auto Features = (*MaybeISAInfo)->toFeatures(AddAllExtensions: true);
598 EXPECT_GT(Features.size(), 1UL);
599 EXPECT_EQ(Features.front(), "+m");
600 // Every feature after should be a negative feature
601 for (auto &NegativeExt : llvm::drop_begin(RangeOrContainer&: Features))
602 EXPECT_TRUE(NegativeExt.substr(0, 1) == "-");
603}
604
605TEST(OrderedExtensionMap, ExtensionsAreCorrectlyOrdered) {
606 RISCVISAInfo::OrderedExtensionMap Exts;
607 for (auto ExtName : {"y", "l", "m", "c", "i", "xfoo", "xbar", "sfoo", "sbar",
608 "zmfoo", "zzfoo", "zfinx", "zicsr"})
609 Exts[ExtName] = {.Major: 1, .Minor: 0};
610
611 std::vector<std::string> ExtNames;
612 for (const auto &Ext : Exts)
613 ExtNames.push_back(x: Ext.first);
614
615 // FIXME: 'l' and 'y' should be ordered after 'i', 'm', 'c'.
616 EXPECT_THAT(ExtNames,
617 ElementsAre("i", "m", "l", "c", "y", "zicsr", "zmfoo", "zfinx",
618 "zzfoo", "sbar", "sfoo", "xbar", "xfoo"));
619}
620
621TEST(ParseArchString, ZceImplication) {
622 auto MaybeRV32IZce = RISCVISAInfo::parseArchString(Arch: "rv32izce", EnableExperimentalExtension: true);
623 ASSERT_THAT_EXPECTED(MaybeRV32IZce, Succeeded());
624 RISCVISAInfo::OrderedExtensionMap ExtsRV32IZce =
625 (*MaybeRV32IZce)->getExtensions();
626 EXPECT_EQ(ExtsRV32IZce.size(), 7UL);
627 EXPECT_EQ(ExtsRV32IZce.count("i"), 1U);
628 EXPECT_EQ(ExtsRV32IZce.count("zicsr"), 1U);
629 EXPECT_EQ(ExtsRV32IZce.count("zca"), 1U);
630 EXPECT_EQ(ExtsRV32IZce.count("zcb"), 1U);
631 EXPECT_EQ(ExtsRV32IZce.count("zce"), 1U);
632 EXPECT_EQ(ExtsRV32IZce.count("zcmp"), 1U);
633 EXPECT_EQ(ExtsRV32IZce.count("zcmt"), 1U);
634
635 auto MaybeRV32IFZce = RISCVISAInfo::parseArchString(Arch: "rv32ifzce", EnableExperimentalExtension: true);
636 ASSERT_THAT_EXPECTED(MaybeRV32IFZce, Succeeded());
637 RISCVISAInfo::OrderedExtensionMap ExtsRV32IFZce =
638 (*MaybeRV32IFZce)->getExtensions();
639 EXPECT_EQ(ExtsRV32IFZce.size(), 9UL);
640 EXPECT_EQ(ExtsRV32IFZce.count("i"), 1U);
641 EXPECT_EQ(ExtsRV32IFZce.count("zicsr"), 1U);
642 EXPECT_EQ(ExtsRV32IFZce.count("f"), 1U);
643 EXPECT_EQ(ExtsRV32IFZce.count("zca"), 1U);
644 EXPECT_EQ(ExtsRV32IFZce.count("zcb"), 1U);
645 EXPECT_EQ(ExtsRV32IFZce.count("zce"), 1U);
646 EXPECT_EQ(ExtsRV32IFZce.count("zcf"), 1U);
647 EXPECT_EQ(ExtsRV32IFZce.count("zcmp"), 1U);
648 EXPECT_EQ(ExtsRV32IFZce.count("zcmt"), 1U);
649
650 auto MaybeRV32IDZce = RISCVISAInfo::parseArchString(Arch: "rv32idzce", EnableExperimentalExtension: true);
651 ASSERT_THAT_EXPECTED(MaybeRV32IDZce, Succeeded());
652 RISCVISAInfo::OrderedExtensionMap ExtsRV32IDZce =
653 (*MaybeRV32IDZce)->getExtensions();
654 EXPECT_EQ(ExtsRV32IDZce.size(), 10UL);
655 EXPECT_EQ(ExtsRV32IDZce.count("i"), 1U);
656 EXPECT_EQ(ExtsRV32IDZce.count("zicsr"), 1U);
657 EXPECT_EQ(ExtsRV32IDZce.count("f"), 1U);
658 EXPECT_EQ(ExtsRV32IDZce.count("d"), 1U);
659 EXPECT_EQ(ExtsRV32IDZce.count("zca"), 1U);
660 EXPECT_EQ(ExtsRV32IDZce.count("zcb"), 1U);
661 EXPECT_EQ(ExtsRV32IDZce.count("zce"), 1U);
662 EXPECT_EQ(ExtsRV32IDZce.count("zcf"), 1U);
663 EXPECT_EQ(ExtsRV32IDZce.count("zcmp"), 1U);
664 EXPECT_EQ(ExtsRV32IDZce.count("zcmt"), 1U);
665
666 auto MaybeRV64IZce = RISCVISAInfo::parseArchString(Arch: "rv64izce", EnableExperimentalExtension: true);
667 ASSERT_THAT_EXPECTED(MaybeRV64IZce, Succeeded());
668 RISCVISAInfo::OrderedExtensionMap ExtsRV64IZce =
669 (*MaybeRV64IZce)->getExtensions();
670 EXPECT_EQ(ExtsRV64IZce.size(), 7UL);
671 EXPECT_EQ(ExtsRV64IZce.count("i"), 1U);
672 EXPECT_EQ(ExtsRV64IZce.count("zicsr"), 1U);
673 EXPECT_EQ(ExtsRV64IZce.count("zca"), 1U);
674 EXPECT_EQ(ExtsRV64IZce.count("zcb"), 1U);
675 EXPECT_EQ(ExtsRV64IZce.count("zce"), 1U);
676 EXPECT_EQ(ExtsRV64IZce.count("zcmp"), 1U);
677 EXPECT_EQ(ExtsRV64IZce.count("zcmt"), 1U);
678
679 auto MaybeRV64IFZce = RISCVISAInfo::parseArchString(Arch: "rv64ifzce", EnableExperimentalExtension: true);
680 ASSERT_THAT_EXPECTED(MaybeRV64IFZce, Succeeded());
681 RISCVISAInfo::OrderedExtensionMap ExtsRV64IFZce =
682 (*MaybeRV64IFZce)->getExtensions();
683 EXPECT_EQ(ExtsRV64IFZce.size(), 8UL);
684 EXPECT_EQ(ExtsRV64IFZce.count("i"), 1U);
685 EXPECT_EQ(ExtsRV64IFZce.count("zicsr"), 1U);
686 EXPECT_EQ(ExtsRV64IFZce.count("f"), 1U);
687 EXPECT_EQ(ExtsRV64IFZce.count("zca"), 1U);
688 EXPECT_EQ(ExtsRV64IFZce.count("zcb"), 1U);
689 EXPECT_EQ(ExtsRV64IFZce.count("zce"), 1U);
690 EXPECT_EQ(ExtsRV64IFZce.count("zcmp"), 1U);
691 EXPECT_EQ(ExtsRV64IFZce.count("zcmt"), 1U);
692
693 EXPECT_EQ(ExtsRV64IFZce.count("zca"), 1U);
694 EXPECT_EQ(ExtsRV64IFZce.count("zcb"), 1U);
695 EXPECT_EQ(ExtsRV64IFZce.count("zce"), 1U);
696 EXPECT_EQ(ExtsRV64IFZce.count("zcmp"), 1U);
697 EXPECT_EQ(ExtsRV64IFZce.count("zcmt"), 1U);
698
699 auto MaybeRV64IDZce = RISCVISAInfo::parseArchString(Arch: "rv64idzce", EnableExperimentalExtension: true);
700 ASSERT_THAT_EXPECTED(MaybeRV64IDZce, Succeeded());
701 RISCVISAInfo::OrderedExtensionMap ExtsRV64IDZce =
702 (*MaybeRV64IDZce)->getExtensions();
703 EXPECT_EQ(ExtsRV64IDZce.size(), 9UL);
704 EXPECT_EQ(ExtsRV64IDZce.count("i"), 1U);
705 EXPECT_EQ(ExtsRV64IDZce.count("zicsr"), 1U);
706 EXPECT_EQ(ExtsRV64IDZce.count("f"), 1U);
707 EXPECT_EQ(ExtsRV64IDZce.count("d"), 1U);
708 EXPECT_EQ(ExtsRV64IDZce.count("zca"), 1U);
709 EXPECT_EQ(ExtsRV64IDZce.count("zcb"), 1U);
710 EXPECT_EQ(ExtsRV64IDZce.count("zce"), 1U);
711 EXPECT_EQ(ExtsRV64IDZce.count("zcmp"), 1U);
712 EXPECT_EQ(ExtsRV64IDZce.count("zcmt"), 1U);
713}
714
715TEST(isSupportedExtensionWithVersion, AcceptsSingleExtensionWithVersion) {
716 EXPECT_TRUE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb1p0"));
717 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb"));
718 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo1p0"));
719 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo"));
720 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion(""));
721 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("c2p0zbb1p0"));
722}
723
724TEST(getTargetFeatureForExtension, RetrieveTargetFeatureFromOneExt) {
725 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbb"), "zbb");
726 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso0p1"),
727 "experimental-ztso");
728 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso"),
729 "experimental-ztso");
730 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zihintntl1234p4321"),
731 "");
732 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zfoo"), "");
733 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension(""), "");
734 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbbzihintntl"), "");
735}
736
737TEST(RiscvExtensionsHelp, CheckExtensions) {
738 // clang-format off
739 std::string ExpectedOutput =
740R"(All available -march extensions for RISC-V
741
742 Name Version Description
743 i 2.1 This is a long dummy description
744 e 2.0
745 m 2.0
746 a 2.1
747 f 2.2
748 d 2.2
749 c 2.0
750 v 1.0
751 h 1.0
752 zic64b 1.0
753 zicbom 1.0
754 zicbop 1.0
755 zicboz 1.0
756 ziccamoa 1.0
757 ziccif 1.0
758 zicclsm 1.0
759 ziccrse 1.0
760 zicntr 2.0
761 zicond 1.0
762 zicsr 2.0
763 zifencei 2.0
764 zihintntl 1.0
765 zihintpause 2.0
766 zihpm 2.0
767 zimop 1.0
768 zmmul 1.0
769 za128rs 1.0
770 za64rs 1.0
771 zacas 1.0
772 zama16b 1.0
773 zawrs 1.0
774 zfa 1.0
775 zfh 1.0
776 zfhmin 1.0
777 zfinx 1.0
778 zdinx 1.0
779 zca 1.0
780 zcb 1.0
781 zcd 1.0
782 zce 1.0
783 zcf 1.0
784 zcmop 1.0
785 zcmp 1.0
786 zcmt 1.0
787 zba 1.0
788 zbb 1.0
789 zbc 1.0
790 zbkb 1.0
791 zbkc 1.0
792 zbkx 1.0
793 zbs 1.0
794 zk 1.0
795 zkn 1.0
796 zknd 1.0
797 zkne 1.0
798 zknh 1.0
799 zkr 1.0
800 zks 1.0
801 zksed 1.0
802 zksh 1.0
803 zkt 1.0
804 zvbb 1.0
805 zvbc 1.0
806 zve32f 1.0
807 zve32x 1.0
808 zve64d 1.0
809 zve64f 1.0
810 zve64x 1.0
811 zvfh 1.0
812 zvfhmin 1.0
813 zvkb 1.0
814 zvkg 1.0
815 zvkn 1.0
816 zvknc 1.0
817 zvkned 1.0
818 zvkng 1.0
819 zvknha 1.0
820 zvknhb 1.0
821 zvks 1.0
822 zvksc 1.0
823 zvksed 1.0
824 zvksg 1.0
825 zvksh 1.0
826 zvkt 1.0
827 zvl1024b 1.0
828 zvl128b 1.0
829 zvl16384b 1.0
830 zvl2048b 1.0
831 zvl256b 1.0
832 zvl32768b 1.0
833 zvl32b 1.0
834 zvl4096b 1.0
835 zvl512b 1.0
836 zvl64b 1.0
837 zvl65536b 1.0
838 zvl8192b 1.0
839 zhinx 1.0
840 zhinxmin 1.0
841 shcounterenw 1.0
842 shgatpa 1.0
843 shtvala 1.0
844 shvsatpa 1.0
845 shvstvala 1.0
846 shvstvecd 1.0
847 smaia 1.0
848 smepmp 1.0
849 ssaia 1.0
850 ssccptr 1.0
851 sscofpmf 1.0
852 sscounterenw 1.0
853 ssstateen 1.0
854 ssstrict 1.0
855 sstc 1.0
856 sstvala 1.0
857 sstvecd 1.0
858 ssu64xl 1.0
859 svade 1.0
860 svadu 1.0
861 svbare 1.0
862 svinval 1.0
863 svnapot 1.0
864 svpbmt 1.0
865 xcvalu 1.0
866 xcvbi 1.0
867 xcvbitmanip 1.0
868 xcvelw 1.0
869 xcvmac 1.0
870 xcvmem 1.0
871 xcvsimd 1.0
872 xsfcease 1.0
873 xsfvcp 1.0
874 xsfvfnrclipxfqf 1.0
875 xsfvfwmaccqqq 1.0
876 xsfvqmaccdod 1.0
877 xsfvqmaccqoq 1.0
878 xsifivecdiscarddlone 1.0
879 xsifivecflushdlone 1.0
880 xtheadba 1.0
881 xtheadbb 1.0
882 xtheadbs 1.0
883 xtheadcmo 1.0
884 xtheadcondmov 1.0
885 xtheadfmemidx 1.0
886 xtheadmac 1.0
887 xtheadmemidx 1.0
888 xtheadmempair 1.0
889 xtheadsync 1.0
890 xtheadvdot 1.0
891 xventanacondops 1.0
892
893Experimental extensions
894 zicfilp 0.4 This is a long dummy description
895 zicfiss 0.4
896 zaamo 0.2
897 zabha 1.0
898 zalasr 0.1
899 zalrsc 0.2
900 zfbfmin 1.0
901 ztso 0.1
902 zvfbfmin 1.0
903 zvfbfwma 1.0
904 smmpm 0.8
905 smnpm 0.8
906 ssnpm 0.8
907 sspm 0.8
908 ssqosid 1.0
909 supm 0.8
910
911Use -march to specify the target's extension.
912For example, clang -march=rv32i_v1p0)";
913 // clang-format on
914
915 StringMap<StringRef> DummyMap;
916 DummyMap["i"] = "This is a long dummy description";
917 DummyMap["experimental-zicfilp"] = "This is a long dummy description";
918
919 outs().flush();
920 testing::internal::CaptureStdout();
921 riscvExtensionsHelp(DescMap: DummyMap);
922 outs().flush();
923
924 std::string CapturedOutput = testing::internal::GetCapturedStdout();
925 EXPECT_TRUE([](std::string &Captured, std::string &Expected) {
926 return Captured.find(Expected) != std::string::npos;
927 }(CapturedOutput, ExpectedOutput));
928}
929

source code of llvm/unittests/TargetParser/RISCVISAInfoTest.cpp