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