1 //===-- unittests/RISCVISAInfoTest.cpp ------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/TargetParser/RISCVISAInfo.h"
10 #include "llvm/ADT/StringMap.h"
11 #include "llvm/Testing/Support/Error.h"
12 #include "gtest/gtest.h"
14 using ::testing::ElementsAre
;
18 bool operator==(const RISCVISAUtils::ExtensionVersion
&A
,
19 const RISCVISAUtils::ExtensionVersion
&B
) {
20 return A
.Major
== B
.Major
&& A
.Minor
== B
.Minor
;
23 TEST(ParseNormalizedArchString
, RejectsInvalidChars
) {
24 for (StringRef Input
: {"RV32", "rV64", "rv32i2P0", "rv64i2p0_A2p0",
25 "rv32e2.0", "rva20u64+zbc"}) {
27 toString(RISCVISAInfo::parseNormalizedArchString(Input
).takeError()),
28 "string may only contain [a-z0-9_]");
32 TEST(ParseNormalizedArchString
, RejectsInvalidBaseISA
) {
33 for (StringRef Input
: {"rv32", "rv64", "rv32j", "rv65i"}) {
35 toString(RISCVISAInfo::parseNormalizedArchString(Input
).takeError()),
36 "arch string must begin with valid base ISA");
40 TEST(ParseNormalizedArchString
, RejectsMalformedInputs
) {
41 for (StringRef Input
: {"rv64e2p", "rv32i", "rv64ip1"}) {
43 toString(RISCVISAInfo::parseNormalizedArchString(Input
).takeError()),
44 "extension lacks version in expected format");
47 for (StringRef Input
: {"rv64i2p0_", "rv32i2p0__a2p0"}) {
49 toString(RISCVISAInfo::parseNormalizedArchString(Input
).takeError()),
50 "extension name missing after separator '_'");
54 TEST(ParseNormalizedArchString
, RejectsOnlyVersion
) {
55 for (StringRef Input
: {"rv64i2p0_1p0", "rv32i2p0_1p0"}) {
57 toString(RISCVISAInfo::parseNormalizedArchString(Input
).takeError()),
58 "missing extension name");
62 TEST(ParseNormalizedArchString
, RejectsBadZ
) {
63 for (StringRef Input
: {"rv64i2p0_z1p0", "rv32i2p0_z2a1p0"}) {
65 toString(RISCVISAInfo::parseNormalizedArchString(Input
).takeError()),
66 "'z' must be followed by a letter");
70 TEST(ParseNormalizedArchString
, RejectsBadS
) {
71 for (StringRef Input
: {"rv64i2p0_s1p0", "rv32i2p0_s2a1p0"}) {
73 toString(RISCVISAInfo::parseNormalizedArchString(Input
).takeError()),
74 "'s' must be followed by a letter");
78 TEST(ParseNormalizedArchString
, RejectsBadX
) {
79 for (StringRef Input
: {"rv64i2p0_x1p0", "rv32i2p0_x2a1p0"}) {
81 toString(RISCVISAInfo::parseNormalizedArchString(Input
).takeError()),
82 "'x' must be followed by a letter");
86 TEST(ParseNormalizedArchString
, DuplicateExtension
) {
87 for (StringRef Input
: {"rv64i2p0_a2p0_a1p0"}) {
89 toString(RISCVISAInfo::parseNormalizedArchString(Input
).takeError()),
90 "duplicate extension 'a'");
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);
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);
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);
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);
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}));
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);
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");
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_]");
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 "
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'");
185 EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv64k", true).takeError()),
186 "first letter after 'rv64' should be 'e', 'i' or 'g'");
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 "
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);
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);
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);
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);
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);
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);
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);
326 TEST(ParseArchString
, RejectsUnrecognizedExtensionNamesByDefault
) {
329 RISCVISAInfo::parseArchString("rv32i_zmadeup", true).takeError()),
330 "unsupported standard user-level extension 'zmadeup'");
333 RISCVISAInfo::parseArchString("rv64g_smadeup", true).takeError()),
334 "unsupported standard supervisor-level extension 'smadeup'");
337 RISCVISAInfo::parseArchString("rv64g_xmadeup", true).takeError()),
338 "unsupported non-standard user-level extension 'xmadeup'");
341 RISCVISAInfo::parseArchString("rv32i_zmadeup1p0", true).takeError()),
342 "unsupported standard user-level extension 'zmadeup'");
345 RISCVISAInfo::parseArchString("rv64g_smadeup1p0", true).takeError()),
346 "unsupported standard supervisor-level extension 'smadeup'");
349 RISCVISAInfo::parseArchString("rv64g_xmadeup1p0", true).takeError()),
350 "unsupported non-standard user-level extension 'xmadeup'");
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}));
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}));
368 TEST(ParseArchString
, RejectsUnrecognizedExtensionVersionsByDefault
) {
370 toString(RISCVISAInfo::parseArchString("rv64i2p", true).takeError()),
371 "minor version number missing after 'p' for extension 'i'");
373 toString(RISCVISAInfo::parseArchString("rv64i1p0", true).takeError()),
374 "unsupported version number 1.0 for extension 'i'");
376 toString(RISCVISAInfo::parseArchString("rv64i9p9", true).takeError()),
377 "unsupported version number 9.9 for extension 'i'");
379 toString(RISCVISAInfo::parseArchString("rv32im0p1", true).takeError()),
380 "unsupported version number 0.1 for extension 'm'");
381 EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv32izifencei10p10", true)
383 "unsupported version number 10.10 for extension 'zifencei'");
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);
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);
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);
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);
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);
474 TEST(ParseArchString
, RejectsRelaxExtensionsNotStartWithEorIorG
) {
476 toString(RISCVISAInfo::parseArchString("rv32zba_im", true).takeError()),
477 "first letter after 'rv32' should be 'e', 'i' or 'g'");
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'");
486 toString(RISCVISAInfo::parseArchString("rv32izbai_m", true).takeError()),
487 "unsupported standard user-level extension 'zbai'");
489 toString(RISCVISAInfo::parseArchString("rv32izbaim", true).takeError()),
490 "unsupported standard user-level extension 'zbaim'");
493 RISCVISAInfo::parseArchString("rv32i_zba1p0m", true).takeError()),
494 "unsupported standard user-level extension 'zba1p0m'");
497 TEST(ParseArchString
, RejectsDoubleOrTrailingUnderscore
) {
499 toString(RISCVISAInfo::parseArchString("rv64i__m", true).takeError()),
500 "extension name missing after separator '_'");
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 '_'");
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'");
515 toString(RISCVISAInfo::parseArchString("rv64imm", true).takeError()),
516 "duplicated standard user-level extension 'm'");
519 RISCVISAInfo::parseArchString("rv32i_zicsr_zicsr", true).takeError()),
520 "duplicated standard user-level extension 'zicsr'");
523 TEST(ParseArchString
,
524 RejectsExperimentalExtensionsIfNotEnableExperimentalExtension
) {
526 toString(RISCVISAInfo::parseArchString("rv64izalasr", false).takeError()),
527 "requires '-menable-experimental-extensions' for experimental extension "
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);
549 TEST(ParseArchString
,
550 RequiresExplicitVersionNumberForExperimentalExtensionByDefault
) {
552 toString(RISCVISAInfo::parseArchString("rv64izalasr", true).takeError()),
553 "experimental extension requires explicit version number `zalasr`");
556 TEST(ParseArchString
,
557 AcceptsUnrecognizedVersionIfNotExperimentalExtensionVersionCheck
) {
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}));
566 TEST(ParseArchString
, RejectsUnrecognizedVersionForExperimentalExtension
) {
569 RISCVISAInfo::parseArchString("rv64izalasr9p9", true).takeError()),
570 "unsupported version number 9.9 for experimental extension 'zalasr' "
571 "(this compiler supports 0.1)");
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'");
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);
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);
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");
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");
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");
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");
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");
636 for (StringRef Input
: {"rv64if_zcf"}) {
637 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input
, true).takeError()),
638 "'zcf' is only supported for 'rv32'");
641 for (StringRef Input
: {"rv64i_xwchc"}) {
642 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input
, true).takeError()),
643 "'xwchc' is only supported for 'rv32'");
646 for (StringRef Input
: {"rv32id_xwchc"}) {
647 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input
, true).takeError()),
648 "'d' and 'xwchc' extensions are incompatible");
651 for (StringRef Input
: {"rv32i_zcb_xwchc"}) {
652 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input
, true).takeError()),
653 "'xwchc' and 'zcb' extensions are incompatible");
656 for (StringRef Input
:
657 {"rv64i_xqcisls0p2", "rv64i_xqcia0p2", "rv64i_xqciac0p2",
658 "rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcics0p2",
659 "rv64i_xqcicli0p2"}) {
661 toString(RISCVISAInfo::parseArchString(Input
, true).takeError()),
662 ::testing::EndsWith(" is only supported for 'rv32'"));
666 TEST(ParseArchString
, MissingDepency
) {
667 for (StringRef Input
: {"rv32i_zvl32b", "rv64i_zvl128b"}) {
668 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input
, true).takeError()),
669 "'zvl*b' requires 'v' or 'zve*' extension to also be specified");
672 // These all have an implication relationship, thus should pass
673 for (StringRef Input
: {
686 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input
, true).takeError()),
691 TEST(ParseArchString
, RejectsUnrecognizedProfileNames
) {
692 for (StringRef Input
: {"rvi23u99", "rvz23u64", "rva99u32"}) {
693 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input
, true).takeError()),
694 "string must begin with rv32{i,e,g}, rv64{i,e,g}, or a supported "
699 TEST(ParseArchString
, RejectsProfilesWithUnseparatedExtraExtensions
) {
700 for (StringRef Input
: {"rvi20u32m", "rvi20u64c"}) {
701 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input
, true).takeError()),
702 "additional extensions must be after separator '_'");
706 TEST(ParseArchString
, AcceptsBareProfileNames
) {
707 auto MaybeRVA20U64
= RISCVISAInfo::parseArchString("rva20u64", true);
708 ASSERT_THAT_EXPECTED(MaybeRVA20U64
, Succeeded());
709 const auto &Exts
= (*MaybeRVA20U64
)->getExtensions();
710 EXPECT_EQ(Exts
.size(), 16UL);
711 EXPECT_EQ(Exts
.count("i"), 1U);
712 EXPECT_EQ(Exts
.count("m"), 1U);
713 EXPECT_EQ(Exts
.count("f"), 1U);
714 EXPECT_EQ(Exts
.count("a"), 1U);
715 EXPECT_EQ(Exts
.count("d"), 1U);
716 EXPECT_EQ(Exts
.count("c"), 1U);
717 EXPECT_EQ(Exts
.count("za128rs"), 1U);
718 EXPECT_EQ(Exts
.count("zicntr"), 1U);
719 EXPECT_EQ(Exts
.count("ziccif"), 1U);
720 EXPECT_EQ(Exts
.count("zicsr"), 1U);
721 EXPECT_EQ(Exts
.count("ziccrse"), 1U);
722 EXPECT_EQ(Exts
.count("ziccamoa"), 1U);
723 EXPECT_EQ(Exts
.count("zicclsm"), 1U);
724 EXPECT_EQ(Exts
.count("zmmul"), 1U);
725 EXPECT_EQ(Exts
.count("zaamo"), 1U);
726 EXPECT_EQ(Exts
.count("zalrsc"), 1U);
728 auto MaybeRVA23U64
= RISCVISAInfo::parseArchString("rva23u64", true);
729 ASSERT_THAT_EXPECTED(MaybeRVA23U64
, Succeeded());
730 EXPECT_GT((*MaybeRVA23U64
)->getExtensions().size(), 13UL);
733 TEST(ParseArchSTring
, AcceptsProfileNamesWithSeparatedAdditionalExtensions
) {
734 auto MaybeRVI20U64
= RISCVISAInfo::parseArchString("rvi20u64_m_zba", true);
735 ASSERT_THAT_EXPECTED(MaybeRVI20U64
, Succeeded());
736 const auto &Exts
= (*MaybeRVI20U64
)->getExtensions();
737 EXPECT_EQ(Exts
.size(), 4UL);
738 EXPECT_EQ(Exts
.count("i"), 1U);
739 EXPECT_EQ(Exts
.count("m"), 1U);
740 EXPECT_EQ(Exts
.count("zba"), 1U);
741 EXPECT_EQ(Exts
.count("zmmul"), 1U);
744 TEST(ParseArchString
,
745 RejectsProfilesWithAdditionalExtensionsGivenAlreadyInProfile
) {
746 // This test was added to document the current behaviour. Discussion isn't
747 // believed to have taken place about if this is desirable or not.
750 RISCVISAInfo::parseArchString("rva20u64_zicntr", true).takeError()),
751 "duplicated standard user-level extension 'zicntr'");
754 TEST(ParseArchString
,
755 RejectsExperimentalProfilesIfEnableExperimentalExtensionsNotSet
) {
757 toString(RISCVISAInfo::parseArchString("rvm23u32", false).takeError()),
758 "requires '-menable-experimental-extensions' for profile 'rvm23u32'");
761 TEST(ToFeatures
, IIsDroppedAndExperimentalExtensionsArePrefixed
) {
763 RISCVISAInfo::parseArchString("rv64im_zalasr", true, false);
764 ASSERT_THAT_EXPECTED(MaybeISAInfo1
, Succeeded());
765 EXPECT_THAT((*MaybeISAInfo1
)->toFeatures(),
766 ElementsAre("+m", "+zmmul", "+experimental-zalasr"));
768 auto MaybeISAInfo2
= RISCVISAInfo::parseArchString(
769 "rv32e_zalasr_xventanacondops", true, false);
770 ASSERT_THAT_EXPECTED(MaybeISAInfo2
, Succeeded());
771 EXPECT_THAT((*MaybeISAInfo2
)->toFeatures(),
772 ElementsAre("+e", "+experimental-zalasr", "+xventanacondops"));
775 TEST(ToFeatures
, UnsupportedExtensionsAreDropped
) {
777 RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0_xmadeup1p0");
778 ASSERT_THAT_EXPECTED(MaybeISAInfo
, Succeeded());
779 EXPECT_THAT((*MaybeISAInfo
)->toFeatures(), ElementsAre("+m"));
782 TEST(ToFeatures
, UnsupportedExtensionsAreKeptIfIgnoreUnknownIsFalse
) {
784 RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0_xmadeup1p0");
785 ASSERT_THAT_EXPECTED(MaybeISAInfo
, Succeeded());
786 EXPECT_THAT((*MaybeISAInfo
)->toFeatures(false, false),
787 ElementsAre("+m", "+xmadeup"));
790 TEST(ToFeatures
, AddAllExtensionsAddsNegativeExtensions
) {
791 auto MaybeISAInfo
= RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0");
792 ASSERT_THAT_EXPECTED(MaybeISAInfo
, Succeeded());
794 auto Features
= (*MaybeISAInfo
)->toFeatures(true);
795 EXPECT_GT(Features
.size(), 1UL);
796 EXPECT_EQ(Features
.front(), "+m");
797 // Every feature after should be a negative feature
798 for (auto &NegativeExt
: llvm::drop_begin(Features
))
799 EXPECT_TRUE(NegativeExt
.substr(0, 1) == "-");
802 TEST(OrderedExtensionMap
, ExtensionsAreCorrectlyOrdered
) {
803 RISCVISAUtils::OrderedExtensionMap Exts
;
804 for (auto ExtName
: {"y", "l", "m", "c", "i", "xfoo", "xbar", "sfoo", "sbar",
805 "zmfoo", "zzfoo", "zfinx", "zicsr"})
806 Exts
[ExtName
] = {1, 0};
808 std::vector
<std::string
> ExtNames
;
809 for (const auto &Ext
: Exts
)
810 ExtNames
.push_back(Ext
.first
);
812 // FIXME: 'l' and 'y' should be ordered after 'i', 'm', 'c'.
813 EXPECT_THAT(ExtNames
,
814 ElementsAre("i", "m", "l", "c", "y", "zicsr", "zmfoo", "zfinx",
815 "zzfoo", "sbar", "sfoo", "xbar", "xfoo"));
818 TEST(ParseArchString
, ZceImplication
) {
819 auto MaybeRV32IZce
= RISCVISAInfo::parseArchString("rv32izce", true);
820 ASSERT_THAT_EXPECTED(MaybeRV32IZce
, Succeeded());
821 const auto &ExtsRV32IZce
= (*MaybeRV32IZce
)->getExtensions();
822 EXPECT_EQ(ExtsRV32IZce
.size(), 7UL);
823 EXPECT_EQ(ExtsRV32IZce
.count("i"), 1U);
824 EXPECT_EQ(ExtsRV32IZce
.count("zicsr"), 1U);
825 EXPECT_EQ(ExtsRV32IZce
.count("zca"), 1U);
826 EXPECT_EQ(ExtsRV32IZce
.count("zcb"), 1U);
827 EXPECT_EQ(ExtsRV32IZce
.count("zce"), 1U);
828 EXPECT_EQ(ExtsRV32IZce
.count("zcmp"), 1U);
829 EXPECT_EQ(ExtsRV32IZce
.count("zcmt"), 1U);
831 auto MaybeRV32IFZce
= RISCVISAInfo::parseArchString("rv32ifzce", true);
832 ASSERT_THAT_EXPECTED(MaybeRV32IFZce
, Succeeded());
833 const auto &ExtsRV32IFZce
= (*MaybeRV32IFZce
)->getExtensions();
834 EXPECT_EQ(ExtsRV32IFZce
.size(), 9UL);
835 EXPECT_EQ(ExtsRV32IFZce
.count("i"), 1U);
836 EXPECT_EQ(ExtsRV32IFZce
.count("zicsr"), 1U);
837 EXPECT_EQ(ExtsRV32IFZce
.count("f"), 1U);
838 EXPECT_EQ(ExtsRV32IFZce
.count("zca"), 1U);
839 EXPECT_EQ(ExtsRV32IFZce
.count("zcb"), 1U);
840 EXPECT_EQ(ExtsRV32IFZce
.count("zce"), 1U);
841 EXPECT_EQ(ExtsRV32IFZce
.count("zcf"), 1U);
842 EXPECT_EQ(ExtsRV32IFZce
.count("zcmp"), 1U);
843 EXPECT_EQ(ExtsRV32IFZce
.count("zcmt"), 1U);
845 auto MaybeRV32IDZce
= RISCVISAInfo::parseArchString("rv32idzce", true);
846 ASSERT_THAT_EXPECTED(MaybeRV32IDZce
, Succeeded());
847 const auto &ExtsRV32IDZce
= (*MaybeRV32IDZce
)->getExtensions();
848 EXPECT_EQ(ExtsRV32IDZce
.size(), 10UL);
849 EXPECT_EQ(ExtsRV32IDZce
.count("i"), 1U);
850 EXPECT_EQ(ExtsRV32IDZce
.count("zicsr"), 1U);
851 EXPECT_EQ(ExtsRV32IDZce
.count("f"), 1U);
852 EXPECT_EQ(ExtsRV32IDZce
.count("d"), 1U);
853 EXPECT_EQ(ExtsRV32IDZce
.count("zca"), 1U);
854 EXPECT_EQ(ExtsRV32IDZce
.count("zcb"), 1U);
855 EXPECT_EQ(ExtsRV32IDZce
.count("zce"), 1U);
856 EXPECT_EQ(ExtsRV32IDZce
.count("zcf"), 1U);
857 EXPECT_EQ(ExtsRV32IDZce
.count("zcmp"), 1U);
858 EXPECT_EQ(ExtsRV32IDZce
.count("zcmt"), 1U);
860 auto MaybeRV64IZce
= RISCVISAInfo::parseArchString("rv64izce", true);
861 ASSERT_THAT_EXPECTED(MaybeRV64IZce
, Succeeded());
862 const auto &ExtsRV64IZce
= (*MaybeRV64IZce
)->getExtensions();
863 EXPECT_EQ(ExtsRV64IZce
.size(), 7UL);
864 EXPECT_EQ(ExtsRV64IZce
.count("i"), 1U);
865 EXPECT_EQ(ExtsRV64IZce
.count("zicsr"), 1U);
866 EXPECT_EQ(ExtsRV64IZce
.count("zca"), 1U);
867 EXPECT_EQ(ExtsRV64IZce
.count("zcb"), 1U);
868 EXPECT_EQ(ExtsRV64IZce
.count("zce"), 1U);
869 EXPECT_EQ(ExtsRV64IZce
.count("zcmp"), 1U);
870 EXPECT_EQ(ExtsRV64IZce
.count("zcmt"), 1U);
872 auto MaybeRV64IFZce
= RISCVISAInfo::parseArchString("rv64ifzce", true);
873 ASSERT_THAT_EXPECTED(MaybeRV64IFZce
, Succeeded());
874 const auto &ExtsRV64IFZce
= (*MaybeRV64IFZce
)->getExtensions();
875 EXPECT_EQ(ExtsRV64IFZce
.size(), 8UL);
876 EXPECT_EQ(ExtsRV64IFZce
.count("i"), 1U);
877 EXPECT_EQ(ExtsRV64IFZce
.count("zicsr"), 1U);
878 EXPECT_EQ(ExtsRV64IFZce
.count("f"), 1U);
879 EXPECT_EQ(ExtsRV64IFZce
.count("zca"), 1U);
880 EXPECT_EQ(ExtsRV64IFZce
.count("zcb"), 1U);
881 EXPECT_EQ(ExtsRV64IFZce
.count("zce"), 1U);
882 EXPECT_EQ(ExtsRV64IFZce
.count("zcmp"), 1U);
883 EXPECT_EQ(ExtsRV64IFZce
.count("zcmt"), 1U);
885 EXPECT_EQ(ExtsRV64IFZce
.count("zca"), 1U);
886 EXPECT_EQ(ExtsRV64IFZce
.count("zcb"), 1U);
887 EXPECT_EQ(ExtsRV64IFZce
.count("zce"), 1U);
888 EXPECT_EQ(ExtsRV64IFZce
.count("zcmp"), 1U);
889 EXPECT_EQ(ExtsRV64IFZce
.count("zcmt"), 1U);
891 auto MaybeRV64IDZce
= RISCVISAInfo::parseArchString("rv64idzce", true);
892 ASSERT_THAT_EXPECTED(MaybeRV64IDZce
, Succeeded());
893 const auto &ExtsRV64IDZce
= (*MaybeRV64IDZce
)->getExtensions();
894 EXPECT_EQ(ExtsRV64IDZce
.size(), 9UL);
895 EXPECT_EQ(ExtsRV64IDZce
.count("i"), 1U);
896 EXPECT_EQ(ExtsRV64IDZce
.count("zicsr"), 1U);
897 EXPECT_EQ(ExtsRV64IDZce
.count("f"), 1U);
898 EXPECT_EQ(ExtsRV64IDZce
.count("d"), 1U);
899 EXPECT_EQ(ExtsRV64IDZce
.count("zca"), 1U);
900 EXPECT_EQ(ExtsRV64IDZce
.count("zcb"), 1U);
901 EXPECT_EQ(ExtsRV64IDZce
.count("zce"), 1U);
902 EXPECT_EQ(ExtsRV64IDZce
.count("zcmp"), 1U);
903 EXPECT_EQ(ExtsRV64IDZce
.count("zcmt"), 1U);
906 TEST(isSupportedExtensionWithVersion
, AcceptsSingleExtensionWithVersion
) {
907 EXPECT_TRUE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb1p0"));
908 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb"));
909 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo1p0"));
910 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo"));
911 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion(""));
912 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("c2p0zbb1p0"));
915 TEST(getTargetFeatureForExtension
, RetrieveTargetFeatureFromOneExt
) {
916 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbb"), "zbb");
917 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso1p0"), "ztso");
918 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso"), "ztso");
919 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zihintntl1234p4321"),
921 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zfoo"), "");
922 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension(""), "");
923 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbbzihintntl"), "");
926 TEST(RiscvExtensionsHelp
, CheckExtensions
) {
928 std::string ExpectedOutput
=
929 R
"(All available -march extensions for RISC-V
931 Name Version Description
932 i 2.1 This is a long dummy description
1091 xsifivecdiscarddlone 1.0
1092 xsifivecflushdlone 1.0
1107 Experimental extensions
1108 zicfilp 1.0 This is a long dummy description
1136 Experimental Profiles
1139 Use -march to specify the target's extension.
1140 For example, clang -march=rv32i_v1p0)";
1143 StringMap
<StringRef
> DummyMap
;
1144 DummyMap
["i"] = "This is a long dummy description";
1145 DummyMap
["experimental-zicfilp"] = "This is a long dummy description";
1148 testing::internal::CaptureStdout();
1149 RISCVISAInfo::printSupportedExtensions(DummyMap
);
1152 std::string CapturedOutput
= testing::internal::GetCapturedStdout();
1153 EXPECT_TRUE([](std::string
&Captured
, std::string
&Expected
) {
1154 return Captured
.find(Expected
) != std::string::npos
;
1155 }(CapturedOutput
, ExpectedOutput
));
1158 TEST(TargetParserTest
, RISCVPrintEnabledExtensions
) {
1160 std::string ExpectedOutput
=
1161 R
"(Extensions enabled for the given RISC-V target
1163 Name Version Description
1164 i 2.1 'I' (Base Integer Instruction Set)
1166 Experimental extensions
1167 zicfilp 1.0 'Zicfilp' (Landing pad)
1169 ISA String: rv64i2p1_zicfilp1p0_zicsr2p0
1173 StringMap
<StringRef
> DescMap
;
1174 DescMap
["i"] = "'I' (Base Integer Instruction Set)";
1175 DescMap
["experimental-zicfilp"] = "'Zicfilp' (Landing pad)";
1176 std::set
<StringRef
> EnabledExtensions
= {"i", "experimental-zicfilp"};
1179 testing::internal::CaptureStdout();
1180 RISCVISAInfo::printEnabledExtensions(/*IsRV64=*/true, EnabledExtensions
,
1183 std::string CapturedOutput
= testing::internal::GetCapturedStdout();
1185 EXPECT_EQ(CapturedOutput
, ExpectedOutput
);